home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / fsinstall / RCS / fsmake.c,v < prev   
Text File  |  1992-04-14  |  106KB  |  4,045 lines

  1. head     1.14;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    jhh:1.14; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.14
  10. date     90.02.17.23.47.50;  author nelson;  state Exp;
  11. branches ;
  12. next     1.13;
  13.  
  14. 1.13
  15. date     89.12.15.15.16.40;  author ouster;  state Exp;
  16. branches ;
  17. next     1.12;
  18.  
  19. 1.12
  20. date     89.12.13.14.06.45;  author rab;  state Exp;
  21. branches ;
  22. next     1.11;
  23.  
  24. 1.11
  25. date     89.11.29.16.49.52;  author ouster;  state Exp;
  26. branches ;
  27. next     1.10;
  28.  
  29. 1.10
  30. date     89.11.27.21.58.00;  author rab;  state Exp;
  31. branches ;
  32. next     1.9;
  33.  
  34. 1.9
  35. date     89.11.27.21.44.16;  author jhh;  state Exp;
  36. branches ;
  37. next     1.8;
  38.  
  39. 1.8
  40. date     89.11.27.14.31.45;  author rab;  state Exp;
  41. branches ;
  42. next     1.7;
  43.  
  44. 1.7
  45. date     89.11.11.22.55.11;  author rab;  state Exp;
  46. branches ;
  47. next     1.6;
  48.  
  49. 1.6
  50. date     89.06.19.13.18.14;  author mnelson;  state Exp;
  51. branches ;
  52. next     1.5;
  53.  
  54. 1.5
  55. date     89.05.19.17.40.11;  author mnelson;  state Exp;
  56. branches ;
  57. next     1.4;
  58.  
  59. 1.4
  60. date     89.05.19.16.56.39;  author mnelson;  state Exp;
  61. branches ;
  62. next     1.3;
  63.  
  64. 1.3
  65. date     89.05.15.19.39.56;  author mnelson;  state Exp;
  66. branches ;
  67. next     1.2;
  68.  
  69. 1.2
  70. date     89.05.03.19.00.24;  author mnelson;  state Exp;
  71. branches ;
  72. next     1.1;
  73.  
  74. 1.1
  75. date     89.05.02.10.50.04;  author mnelson;  state Exp;
  76. branches ;
  77. next     ;
  78.  
  79.  
  80. desc
  81. @@
  82.  
  83.  
  84. 1.14
  85. log
  86. @Added ``newLabel'' option.
  87. @
  88. text
  89. @/* 
  90.  * fsmake.c --
  91.  *
  92.  *    Make a sprite file system on a raw disk.
  93.  *
  94.  * IMPORTANT NOTE ABOUT PORTABILITY:
  95.  *
  96.  *    I use the sprite directory format even when I am reading a UNIX
  97.  *    directory.  I can get a way with this because they are the same.  The
  98.  *    reason why I don't use the UNIX one is that on a PMAX there are some
  99.  *    defines in "/usr/include/sys/dir.h" which screw up the compilation
  100.  *    of this file.  If this runs on a UNIX system that does not have
  101.  *    a compatible directory format then the code in CopyTree must be
  102.  *    modified.
  103.  *
  104.  * Copyright (C) 1989 by Digital Equipment Corporation, Maynard MA
  105.  *
  106.  *            All Rights Reserved
  107.  *
  108.  * Permission to use, copy, modify, and distribute this software and its 
  109.  * documentation for any purpose and without fee is hereby granted, 
  110.  * provided that the above copyright notice appear in all copies and that
  111.  * both that copyright notice and this permission notice appear in 
  112.  * supporting documentation, and that the name of Digital not be
  113.  * used in advertising or publicity pertaining to distribution of the
  114.  * software without specific, written prior permission.  
  115.  *
  116.  * Digitial disclaims all warranties with regard to this software, including
  117.  * all implied warranties of merchantability and fitness.  In no event shall
  118.  * Digital be liable for any special, indirect or consequential damages or
  119.  * any damages whatsoever resulting from loss of use, data or profits,
  120.  * whether in an action of contract, negligence or other tortious action,
  121.  * arising out of or in connection with the use or performance of this
  122.  * software.
  123.  */
  124.  
  125. #ifndef lint
  126. static char rcsid[] = "$Header: /sprite/src/admin/fsinstall/RCS/fsmake.c,v 1.13 89/12/15 15:16:40 ouster Exp $ SPRITE (Berkeley)";
  127. #endif
  128.  
  129. #include "sprite.h"
  130. #include "option.h"
  131. #include "diskUtils.h"
  132. #include <stdio.h>
  133. #include <sys/file.h>
  134. #include <stdlib.h>
  135. #include <string.h>
  136. #include <sys/types.h>
  137. #include <sys/stat.h>
  138. #include <sys/dir.h>
  139. #include <assert.h>
  140. #include <sys/time.h>
  141.  
  142. #ifdef direct
  143. #undef direct
  144. #endif
  145.  
  146. #if defined(sprite) || defined(sun)
  147. #define S_GFDIR     S_IFDIR
  148. #define S_GFMT      S_IFMT
  149. #define S_GFLNK     S_IFLNK
  150. #define S_GFREG      S_IFREG
  151. #endif
  152.  
  153. /*
  154.  * Constants settable via the command line.
  155.  */
  156. int kbytesToFileDesc = 4;    /* The ratio of kbytes to
  157.                  * the number of file descriptors */
  158. Boolean printOnly = FALSE;    /* Stop after computing the domain header
  159.                  * and just print it out. No disk writes */
  160. Boolean overlapBlocks = FALSE;    /* Allow filesystem blocks to overlap track
  161.                  * boundaries.  Some disk systems can't deal. */
  162. char *deviceName;        /* Set to "rsd0" or "rxy1", etc. */
  163. char *partName;            /* Set to "a", "b", "c" ... "g" */
  164. char defaultFirstPartName[] = "a";
  165. char *diskType = NULL;        /* Type of disk (e.g. rz23) */
  166. int  spriteID = 1;        /* This machines sprite id. */
  167. char *devFileName = NULL;    /* Name of file that contains devices to 
  168.                  * create. */
  169. char *dirName = NULL;        /* Name of directory that contains files to
  170.                  * copy to the disk. */
  171. Boolean newLabel = FALSE;
  172.  
  173. Option optionArray[] = {
  174.     {OPT_STRING, "dev", (Address)&deviceName,
  175.     "Required: Name of device, eg \"rsd0\" or \"rxy1\""},
  176.     {OPT_STRING, "part", (Address)&partName,
  177.     "Required: Partition ID: (a, b, c, d, e, f, g)"},
  178.     {OPT_TRUE, "overlap", (Address)&overlapBlocks,
  179.     "Overlap filesystem blocks across track boundaries (FALSE)"},
  180.     {OPT_INT, "ratio", (Address)&kbytesToFileDesc,
  181.     "Ratio of Kbytes to file descriptors (4)"},
  182.     {OPT_TRUE, "test", (Address)&printOnly,
  183.     "Test: print results, don't write disk (FALSE)"},
  184.     {OPT_FALSE, "write", (Address)&printOnly,
  185.     "Write the disk (TRUE)"},
  186.     {OPT_STRING, "type", (Address)&diskType,
  187.     "Type of disk.  Used to look up disk info in /etc/disktab"},
  188.     {OPT_INT, "sid", (Address)&spriteID,
  189.     "Sprite ID of this workstation"},
  190.     {OPT_STRING, "dir", (Address)&dirName,
  191.     "Directory to copy files from"},
  192.     {OPT_STRING, "devFile", (Address)&devFileName,
  193.     "File that contains devices to create"},
  194.     {OPT_TRUE, "newLabel", (Address)&newLabel,
  195.     "Overwrite the current label on the disk if there is one"},
  196. };
  197. int numOptions = sizeof(optionArray) / sizeof(Option);
  198.  
  199. /*
  200.  * Structure used to peruse Sprite directories.
  201.  */
  202. typedef struct DirIndexInfo {
  203.     Fsdm_FileDescriptor *fdPtr;                  /* The file descriptor being
  204.                           * read. */
  205.     int         blockNum;             /* Block that is being read, 
  206.                           * written, or allocated. */
  207.     int         blockAddr;             /* Address of directory block
  208.                           * to read. */
  209.     int         dirOffset;             /* Offset of the directory entry 
  210.                           * that we are currently examining 
  211.                           * in the directory. */
  212.     char     dirBlock[FS_BLOCK_SIZE];    /* Where directory data is 
  213.                           * stored. */
  214. } DirIndexInfo;
  215.  
  216. /*
  217.  * Time of day when this program runs.
  218.  */
  219.  
  220. struct timeval curTime;
  221.  
  222. /*
  223.  * Forward Declarations.
  224.  */
  225. void        SetSummaryInfo();
  226. void        SetDomainHeader();
  227. void        SetDiskGeometry();
  228. void        SetDomainParts();
  229. void        WriteAllFileDescs();
  230. void        WriteAndInitDataBitmap();
  231. unsigned char    *ReadFileDescBitmap();
  232. void        WriteFileDescBitmap();
  233. unsigned char    *ReadBitmap();
  234. void        WriteBitmap();
  235. char         *MakeFileDescBitmap();
  236. Disk_Info    *ScanDiskTab();
  237. static Fslcl_DirEntry    *OpenDir();
  238. Fslcl_DirEntry    *NextDirEntry();
  239. static void        CloseDir();
  240. Fslcl_DirEntry    *AddToDirectory();
  241. void        CreateDir();
  242. void        MarkDataBitmap();
  243. void        InitDesc();
  244. void        CopyTree();
  245. void        ReadFileDesc();
  246. void        WriteFileDesc();
  247. void        MakeDevices();
  248. void        WriteRootDirectory();
  249.  
  250. /*
  251.  * Macro to get a pointer into the bit map for a particular block.
  252.  */
  253. #define BlockToCylinder(domainPtr, blockNum) \
  254.     (blockNum) / (domainPtr)->geometry.blocksPerCylinder
  255.  
  256. #define GetBitmapPtr(domainPtr, bitmapPtr, blockNum) \
  257.   &((bitmapPtr)[BlockToCylinder(domainPtr, blockNum) * \
  258.   bytesPerCylinder + (blockNum) % (domainPtr)->geometry.blocksPerCylinder / 2])
  259.  
  260. /*
  261.  * Macros to convert physical block numbers to virtual block numbers. All direct
  262.  * blocks are virtual, indirect blocks are physical.
  263.  */
  264. #define VirtToPhys(blockNum) \
  265.     ((blockNum) + (domainPtr)->dataOffset * FS_FRAGMENTS_PER_BLOCK)
  266.  
  267. #define PhysToVirt(domainPtr,blockNum) \
  268.     ((blockNum) - (domainPtr)->dataOffset * FS_FRAGMENTS_PER_BLOCK)
  269.  
  270. /*
  271.  * Macro to mark the file descriptor bit map.
  272.  */
  273. #define MarkFDBitmap(num,bitmapPtr) \
  274.     (bitmapPtr)[(num) >> 3] |= (1 << (7 -((num)  & 7)))
  275.  
  276. int            freeFDNum;    /* The currently free file descriptor.*/
  277. int            freeBlockNum;    /* The currently free data block. */
  278. Fsdm_FileDescriptor    devFD;        /* The file descriptor for the dev
  279.                          * directory. */
  280. Fsdm_FileDescriptor    *devFDPtr;    /* Pointer to the file descriptor for
  281.                      * the dev directory. */
  282. int            devFDNum;    /* The file number of the dev 
  283.                      * directory. */
  284. int            partFID;    /* The file id of the partition that
  285.                      * we are initializing. */
  286. Fsdm_DomainHeader         *domainPtr;    /* The domain the we are initializing.*/
  287. int            partition;    /* The partition that we are 
  288.                      * initializing. */
  289. Disk_Info        *diskInfoPtr;    /* Information about the disk that
  290.                      * we are initializing. */
  291. Fsdm_SummaryInfo         *summaryPtr;    /* Summary information for the domain.*/
  292. unsigned char        *fdBitmapPtr;    /* Pointer to the file descriptor
  293.                      * bitmap. */
  294. unsigned char        *cylBitmapPtr;    /* Pointer to the cylinder bit map. */
  295. int            bytesPerCylinder;/* The number of bytes in
  296.                       * the bitmap for a cylinder.*/
  297.  
  298.  
  299.  
  300. /*
  301.  * Some number of sectors in the root partition must be allocated to the
  302.  * boot program. The default is for the new filesystem to have the same
  303.  * number of boot sectors as the old filesystem. If the disk did not
  304.  * previously have a filesystem, or if the domain header cannot be found,
  305.  * then the following number of boot sectors are allocated. The standard
  306.  * Sun format is for the summary sector to be in sector #17. 16 boot sectors
  307.  * and one disk label fill the first 17 sectors.
  308.  */
  309. int    defaultBootSectors = 16;
  310.  
  311. int bootSectors = -1;
  312.  
  313.  
  314. /*
  315.  *----------------------------------------------------------------------
  316.  *
  317.  * main --
  318.  *
  319.  *    Create the required file names from the command line
  320.  *    arguments.  Then open the first partition on the disk
  321.  *    because it contains the disk label, and open the partition
  322.  *    that is to be formatted.
  323.  *
  324.  * Results:
  325.  *    None.
  326.  *
  327.  * Side effects:
  328.  *    Calls MakeFilesystem
  329.  *
  330.  *----------------------------------------------------------------------
  331.  */
  332. main(argc, argv)
  333.     int        argc;
  334.     char    *argv[];
  335. {
  336.     char    answer[10];
  337.     char    partitionName[64];
  338.     int        status;
  339.     static      char block[DEV_BYTES_PER_SECTOR];
  340.     int         i;
  341.  
  342.     gettimeofday(&curTime, NULL);
  343.  
  344.     (void)Opt_Parse(argc, argv, optionArray, numOptions, 0);
  345.  
  346.     if (deviceName == (char *)0) {
  347.     fprintf(stderr,"Specify device name with -dev option\n");
  348.     exit(1);
  349.     }
  350.     if (partName == (char *)0) {
  351.     fprintf(stderr,"Specify partition with -part option\n");
  352.     exit(1);
  353.     } 
  354.     if (spriteID == 0) {
  355.     fprintf(stderr, "Specify sprite id with -sid option\n");
  356.     exit(1);
  357.     }
  358.  
  359.     bootSectors = defaultBootSectors;
  360.  
  361.     if (!printOnly) {
  362.     printf("The \"-write\" option will cause fsmake to overwrite the current filesystem.\nDo you really want to do this?[y/n] ");
  363.     if (scanf("%10s",answer) != 1) {
  364.         exit(0);
  365.     }
  366.     if ((*answer != 'y') && (*answer != 'Y')) {
  367.         exit(0);
  368.     }
  369.     }
  370.  
  371.     if (partName[0] != 'a' && partName[0] != 'c') {
  372.     fprintf(stderr, "Can only format partitions a or c\n");
  373.     exit(1);
  374.     }
  375.  
  376.     /*
  377.      * Gen up the name of the first partition on the disk.
  378.      */
  379.     sprintf(partitionName, "/dev/%s%s", deviceName, partName);
  380.  
  381.     if (printOnly) {
  382.     partFID = open(partitionName, O_RDONLY);
  383.     } else {
  384.     partFID = open(partitionName, O_RDWR);
  385.     }
  386.     if (partFID < 0 ) {
  387.     perror("Can't open first partition");
  388.     exit(1);
  389.     }
  390.  
  391.     printf("fsmake based on 4K filesystem blocks\n");
  392.  
  393.     partition = partName[0] - 'a';
  394.  
  395.     diskInfoPtr = NULL;
  396.     if (!newLabel) {
  397.     /*
  398.      * See if we can read the copy of the super block at the beginning
  399.      * of the partition to find out basic disk geometry and where to
  400.      * write the domain header.  This will only work with disks that
  401.      * have either a sun label or a sprite label.
  402.      */
  403.     diskInfoPtr = Disk_ReadDiskInfo(partFID, partition);
  404.     }
  405.     if (diskInfoPtr == NULL && diskType != NULL) {
  406.     /*
  407.      * See if we can find the information in /etc/disktab.
  408.      */
  409.     diskInfoPtr = ScanDiskTab();
  410.     }
  411.     if (diskInfoPtr == NULL) {
  412.     fprintf(stderr,"MakeFilesystem: Unable to read super block.\n");
  413.     return(1);
  414.     }
  415.  
  416.     /*
  417.      * Clear out the old summary sector and domain header. This is especially
  418.      * important if we are going to move them.
  419.      */
  420.     if ((!printOnly) && (diskInfoPtr->summarySector != -1)) {
  421.     status = Disk_SectorWrite(partFID, diskInfoPtr->summarySector,1, block);
  422.     if (status != SUCCESS) {
  423.         perror("Clear of old summary sector failed"); 
  424.         return(status);
  425.     }
  426.     for (i = 0; i < diskInfoPtr->numDomainSectors; i++) {
  427.         status = Disk_SectorWrite(partFID, diskInfoPtr->domainSector+i,
  428.                 1, block);
  429.         if (status != SUCCESS) {
  430.         perror("Clear of old domain header failed"); 
  431.         return(status);
  432.         }
  433.     }
  434.     }
  435.     /* 
  436.      * The disk did not previously have a filesystem on it.
  437.      */
  438.     if (diskInfoPtr->summarySector == -1) {
  439.     diskInfoPtr->summarySector = bootSectors + 1;
  440.     diskInfoPtr->domainSector = bootSectors + 2;
  441.     }
  442.     domainPtr = (Fsdm_DomainHeader *)
  443.     malloc((unsigned) diskInfoPtr->numDomainSectors * DEV_BYTES_PER_SECTOR);
  444.     SetDomainHeader();
  445.     bytesPerCylinder = (domainPtr->geometry.blocksPerCylinder + 1) / 2;
  446.     Disk_PrintDomainHeader(domainPtr);
  447.  
  448.     if (!printOnly) {
  449.     assert(diskInfoPtr->domainSector >= 0);
  450.     status = Disk_SectorWrite(partFID, diskInfoPtr->domainSector,
  451.                 diskInfoPtr->numDomainSectors, (Address)domainPtr);
  452.     if (status != 0) {
  453.         perror("DomainHeader write failed");
  454.         return(status);
  455.     }
  456.     }
  457.  
  458.     summaryPtr = (Fsdm_SummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  459.     SetSummaryInfo();
  460.     Disk_PrintSummaryInfo(summaryPtr);
  461.     if (!printOnly) {
  462.     assert(diskInfoPtr->summarySector >= 0);
  463.     status = Disk_SectorWrite(partFID, diskInfoPtr->summarySector, 1,
  464.                 (Address)summaryPtr);
  465.     if (status != 0) {
  466.         perror("Summary sector write failed");
  467.         return(status);
  468.     }
  469.     }
  470.  
  471.     WriteAllFileDescs();
  472.     WriteAndInitDataBitmap();
  473.     WriteRootDirectory();
  474.  
  475.     /*
  476.      * We now have a good empty file system.  Add any files and devices
  477.      * that need to be added.
  478.      */
  479.     if (dirName != NULL) {
  480.     Fsdm_FileDescriptor    rootDesc;
  481.  
  482.     fdBitmapPtr = ReadFileDescBitmap();
  483.     freeFDNum = 3;
  484.     cylBitmapPtr = ReadBitmap();
  485.     freeBlockNum = 1;
  486.     ReadFileDesc(FSDM_ROOT_FILE_NUMBER, &rootDesc);
  487.     CopyTree(dirName, FSDM_ROOT_FILE_NUMBER, &rootDesc,
  488.         FSDM_ROOT_FILE_NUMBER, FALSE, "/");
  489.     WriteFileDesc(FSDM_ROOT_FILE_NUMBER, &rootDesc);
  490.     if (devFileName != NULL) {
  491.         if (devFDPtr == NULL) {
  492.         fprintf(stderr, "Couldn't find /dev\n");
  493.         exit(1);
  494.         }
  495.         MakeDevices();
  496.     }
  497.     if (!printOnly) {
  498.         assert(diskInfoPtr->summarySector);
  499.         status = Disk_SectorWrite(partFID, diskInfoPtr->summarySector, 1,
  500.                 (Address)summaryPtr);
  501.         if (status != 0) {
  502.         perror("Summary sector write failed (2)");
  503.         exit(status);
  504.         }
  505.         WriteFileDescBitmap(fdBitmapPtr);
  506.         WriteBitmap(cylBitmapPtr);
  507.     }
  508.     }
  509.  
  510.     fflush(stderr);
  511.     fflush(stdout);
  512.     (void)close(partFID);
  513.     exit(0);
  514. }
  515.  
  516.  
  517. /*
  518.  *----------------------------------------------------------------------
  519.  *
  520.  * SetDomainHeader --
  521.  *
  522.  *    Compute the domain header based on the partition size and
  523.  *    other basic disk parameters.
  524.  *
  525.  * Results:
  526.  *    A return code.
  527.  *
  528.  * Side effects:
  529.  *    Fill in the domain header.
  530.  *
  531.  *----------------------------------------------------------------------
  532.  */
  533. void
  534. SetDomainHeader()
  535. {
  536.     register Fsdm_Geometry *geoPtr;
  537.  
  538.     domainPtr->magic = FSDM_DOMAIN_MAGIC;
  539.     domainPtr->firstCylinder = diskInfoPtr->firstCylinder;
  540.     domainPtr->numCylinders = diskInfoPtr->numCylinders;
  541.     /*
  542.      * The device.serverID from the disk is used during boot to discover
  543.      * the host"s spriteID if reverse arp couldn't find a host ID.  The
  544.      * unit number of disk indicates what partition of the disk this
  545.      * domain header applies to.  For example, both the "a" and "c" partitions
  546.      * typically start at sector zero, but only one is valid.  During boot
  547.      * time the unit number is used to decide which partition should be
  548.      * attached.
  549.      */
  550.     domainPtr->device.serverID = spriteID;
  551.     domainPtr->device.type = -1;
  552.     domainPtr->device.unit = partition;
  553.     domainPtr->device.data = (ClientData)-1;
  554.  
  555.     geoPtr = &domainPtr->geometry;
  556.     SetDiskGeometry(&domainPtr->geometry);
  557.  
  558.     SetDomainParts();
  559. }
  560.  
  561. /*
  562.  *----------------------------------------------------------------------
  563.  *
  564.  * SetDiskGeometry --
  565.  *
  566.  *    This computes the rotational set arrangment depending on the
  567.  *    disk geometry.  The basic rules for this are that filesystem blocks
  568.  *    are skewed on successive tracks, and that the skewing pattern
  569.  *    repeats in either 2 or 4 tracks.  This is specific to the fact that
  570.  *    filesystem blocks are 4Kbytes.  This means that one disk track
  571.  *    contains N/4 filesystem blocks and that one sector per track
  572.  *    is wasted if there are an odd number of sectors per track.
  573.  *
  574.  * Results:
  575.  *    None.
  576.  *
  577.  * Side effects:
  578.  *    Fill in the geometry struct.
  579.  *
  580.  *----------------------------------------------------------------------
  581.  */
  582. void
  583. SetDiskGeometry(geoPtr)
  584.     register Fsdm_Geometry    *geoPtr;    /* Fancy geometry information */
  585. {
  586.     int index;            /* Array index */
  587.     int numBlocks;        /* The number of blocks in a rotational set */
  588.     int tracksPerSet;        /* Total number of tracks in a rotational set */
  589.     int numTracks;        /* The number of tracks in the set so far */
  590.     int extraSectors;        /* The number of leftover sectors in a track */
  591.     int offset;            /* The sector offset within a track */
  592.     int startingOffset;        /* The offset of the first block in a track */
  593.     int offsetIncrement;    /* The skew of the starting offset on each
  594.                  * successive track of the rotational set */
  595.     Boolean overlap;        /* TRUE if filesystem blocks overlap tracks */
  596.  
  597.     geoPtr->numHeads = diskInfoPtr->numHeads;
  598.     geoPtr->sectorsPerTrack = diskInfoPtr->numSectors;
  599.  
  600.     /*
  601.      * Figure out some basic parameters of the rotational set.  The number
  602.      * of tracks in the set is either 2 or 4.  If 2, then the blocks on
  603.      * successive tracks are skewed by 1/2 a filesystem block.  If 4,
  604.      * blocks are skewed by 1/4 block.  A 4 track rotational set is best
  605.      * becasue there are more rotational positions.  If, however, it
  606.      * causes 2 or 3 wasted tracks at the end, or if blocks naturally
  607.      * overlap by 1/2 block, then only 2 tracks per rotational set are
  608.      * used.
  609.      */
  610.     switch(geoPtr->numHeads % 4) {
  611.     case 0:
  612.     case 1: {
  613.         extraSectors = geoPtr->sectorsPerTrack % DISK_SECTORS_PER_BLOCK;
  614.         if (extraSectors < DISK_SECTORS_PER_BLOCK/4) {
  615.         /*
  616.          * Not enough extra sectors to overlap blocks onto the
  617.          * next track.  The blocks will fit evenly on a track,
  618.          * but the blocks on the following tracks will be skewed.
  619.          */
  620.         tracksPerSet = 4;
  621.         overlap = FALSE;
  622.         offsetIncrement = DISK_SECTORS_PER_BLOCK/4;
  623.         } else if (extraSectors < DISK_SECTORS_PER_BLOCK/2) {
  624.         /*
  625.          * Enough to overlap the first 1/4 block onto the next track.
  626.          */
  627.         tracksPerSet = 4;
  628.         overlap = TRUE;
  629.         offsetIncrement = DISK_SECTORS_PER_BLOCK * 3/4;
  630.         } else if (extraSectors < DISK_SECTORS_PER_BLOCK * 3/4) {
  631.         /*
  632.          * Enough to overlap 1/2 block.
  633.          */
  634.         tracksPerSet = 2;
  635.         overlap = TRUE;
  636.         offsetIncrement = DISK_SECTORS_PER_BLOCK/2;
  637.         } else {
  638.         /*
  639.          * Enough to overlap 3/4 block.
  640.          */
  641.         tracksPerSet = 4;
  642.         overlap = TRUE;
  643.         offsetIncrement = DISK_SECTORS_PER_BLOCK/4;
  644.         }
  645.         break;
  646.     }
  647.     case 2:
  648.     case 3: {
  649.         /*
  650.          * Instead of wasting 2 or 3 tracks to have a 4 track rotational
  651.          * set, the rotational set is only 2 tracks long.  Also see if
  652.          * the blocks naturally overlap by 1/2 block.
  653.          */
  654.         tracksPerSet = 2;
  655.         offsetIncrement = DISK_SECTORS_PER_BLOCK/2;
  656.         if ((geoPtr->sectorsPerTrack % DISK_SECTORS_PER_BLOCK) <
  657.               DISK_SECTORS_PER_BLOCK/2) {
  658.         overlap = FALSE;
  659.         } else {
  660.         overlap = TRUE;
  661.         }
  662.     }
  663.     }
  664.     if (!overlapBlocks) {
  665.     overlap = FALSE;
  666.     offsetIncrement = 0;
  667.     }
  668.     printf("overlap %s, offsetIncrement %d\n", (overlap ? "TRUE" : "FALSE"),
  669.               offsetIncrement);
  670.     /*
  671.      * Determine rotational position of the blocks in the rotational set.
  672.      */
  673.     extraSectors = geoPtr->sectorsPerTrack;
  674.     startingOffset = 0;
  675.     offset = startingOffset;
  676.     for (numBlocks = 0, numTracks = 0 ; ; ) {
  677.     if (extraSectors >= DISK_SECTORS_PER_BLOCK) {
  678.         /*
  679.          * Ok to fit in another filesystem block on this track.
  680.          */
  681.         geoPtr->blockOffset[numBlocks] = offset;
  682.         numBlocks++;    
  683.         offset += DISK_SECTORS_PER_BLOCK;
  684.         extraSectors -= DISK_SECTORS_PER_BLOCK;
  685.     } else {
  686.         /*
  687.          * The current block has to take up room on the next track.
  688.          */
  689.         numTracks++;
  690.         if (numTracks < tracksPerSet) {
  691.         /*
  692.          * Ok to go to the next track.
  693.          */
  694.         startingOffset += offsetIncrement;
  695.         if (overlap) {
  696.             /*
  697.              * If the current block can overlap to the next track,
  698.              * use the current offset.  Because of the overlap
  699.              * there are fewer sectors available for blocks on
  700.              * the next track.
  701.              */
  702.             geoPtr->blockOffset[numBlocks] = offset;
  703.             numBlocks++;
  704.             extraSectors = geoPtr->sectorsPerTrack - startingOffset;
  705.         }
  706.         offset = startingOffset + numTracks * geoPtr->sectorsPerTrack;
  707.         if (!overlap) {
  708.             /*
  709.              * If no overlap the whole next track is available.
  710.              */
  711.             extraSectors = geoPtr->sectorsPerTrack;
  712.         }
  713.         } else {
  714.         /*
  715.          * Done.
  716.          */
  717.         for (index = numBlocks; index < FSDM_MAX_ROT_POSITIONS; index++){
  718.             geoPtr->blockOffset[index] = -1;
  719.         }
  720.         break;
  721.         }
  722.     }
  723.     }
  724.     geoPtr->blocksPerRotSet = numBlocks;
  725.     geoPtr->tracksPerRotSet = tracksPerSet;
  726.     geoPtr->rotSetsPerCyl = geoPtr->numHeads / tracksPerSet;
  727.     geoPtr->blocksPerCylinder = numBlocks * geoPtr->rotSetsPerCyl;
  728.  
  729.     /*
  730.      * Now the rotational positions have to be sorted so that rotationally
  731.      * optimal blocks can be found.  The array sortedOffsets is set so
  732.      * that the I'th element has the index into blockOffset which contains
  733.      * the I'th rotational position, eg.
  734.      *    blockOffset    sortedOffsets
  735.      *        0 (+0)        0
  736.      *        8 (+0)        2
  737.      *        4 (+17)        1
  738.      *       12 (+17)        3
  739.      */
  740.  
  741.     offsetIncrement = DISK_SECTORS_PER_BLOCK / tracksPerSet;
  742.     for (index = 0 ; index < FSDM_MAX_ROT_POSITIONS ; index++) {
  743.     geoPtr->sortedOffsets[index] = -1;
  744.     }
  745.     for (index = 0 ; index < numBlocks ; index++) {
  746.     offset = geoPtr->blockOffset[index] % geoPtr->sectorsPerTrack;
  747.     geoPtr->sortedOffsets[offset/offsetIncrement] = index;
  748.     }
  749. }
  750.  
  751. /*
  752.  *----------------------------------------------------------------------
  753.  *
  754.  * SetDomainParts --
  755.  *
  756.  *    Set up the way the domain is divided into 4 areas:  the bitmap
  757.  *    for the file descriptors, the file descriptors, the bitmap for
  758.  *    the data blocks, and the data blocks.
  759.  *
  760.  * Results:
  761.  *    The geometry information is completed.
  762.  *
  763.  * Side effects:
  764.  *    None.
  765.  *
  766.  *----------------------------------------------------------------------
  767.  */
  768. void
  769. SetDomainParts()
  770. {
  771.     register Fsdm_Geometry *geoPtr;
  772.     int            numFiles;
  773.     int         numBlocks;
  774.     int         offset;    
  775.     int         numSectors;
  776.     int            numSets;
  777.     int         bitmapBytes;
  778.  
  779.     /*
  780.      * Set aside a number of blocks at the begining of the partition for
  781.      * things like the super block, the boot program, and the domain header.
  782.      * It is easiest to do this by reserving one or more rotational sets.
  783.      */
  784.     geoPtr = &domainPtr->geometry;
  785.     numSectors = geoPtr->tracksPerRotSet * geoPtr->sectorsPerTrack;
  786.     for ( numSets = 1; ; numSets++ ) {
  787.     if (numSets * numSectors >
  788.         diskInfoPtr->domainSector + diskInfoPtr->numDomainSectors) {
  789.         break;
  790.     }
  791.     }
  792.     printf("Reserving %d blocks for domain header, etc.\n",
  793.             numSets*geoPtr->blocksPerRotSet);
  794.     /*
  795.      * Determine the number of filesystem blocks available and compute a
  796.      * first guess at the number of file descriptors.  If at the end of
  797.      * the computation things don't fit nicely, then the number of files
  798.      * is changed and the computation is repeated.
  799.      */
  800.     numFiles = 0;
  801.     do {
  802.     numBlocks = geoPtr->blocksPerCylinder * diskInfoPtr->numCylinders -
  803.             numSets * geoPtr->blocksPerRotSet;
  804.     if (numFiles == 0) {
  805.         numFiles = numBlocks * DISK_KBYTES_PER_BLOCK / kbytesToFileDesc;
  806.     }
  807.     numFiles          &= ~(FSDM_FILE_DESC_PER_BLOCK-1);
  808.     offset              = numSets * geoPtr->blocksPerRotSet;
  809.  
  810.     domainPtr->fdBitmapOffset = offset;
  811.     bitmapBytes          = (numFiles - 1) / BITS_PER_BYTE + 1;
  812.     domainPtr->fdBitmapBlocks = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  813.     numBlocks          -= domainPtr->fdBitmapBlocks;
  814.     offset              += domainPtr->fdBitmapBlocks;
  815.  
  816.     domainPtr->fileDescOffset = offset;
  817.     domainPtr->numFileDesc      = numFiles;
  818.     numBlocks          -= numFiles / FSDM_FILE_DESC_PER_BLOCK;
  819.     offset              += numFiles / FSDM_FILE_DESC_PER_BLOCK;
  820.     /*
  821.      * The data blocks will start on a cylinder.  Try the next
  822.      * cylinder boundary after the start of the bitmap.
  823.      */
  824.     domainPtr->bitmapOffset      = offset;
  825.     domainPtr->dataOffset      = ((offset-1) / geoPtr->blocksPerCylinder + 1)
  826.                      * geoPtr->blocksPerCylinder;
  827.     domainPtr->dataBlocks      = domainPtr->numCylinders *
  828.                       geoPtr->blocksPerCylinder -
  829.                       domainPtr->dataOffset;
  830.     bitmapBytes          = (domainPtr->dataBlocks * DISK_KBYTES_PER_BLOCK -
  831.                        1) / BITS_PER_BYTE + 1;
  832.     domainPtr->bitmapBlocks      = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  833.     /*
  834.      * Check the size of the bit map against space available for it
  835.      * between the end of the file descriptors and the start of the
  836.      * data blocks.
  837.      */
  838.     if (domainPtr->dataOffset - domainPtr->bitmapOffset <
  839.         domainPtr->bitmapBlocks) {
  840.         int numBlocksNeeded;
  841.         /*
  842.          * Need more blocks to hold the bitmap.  Reduce the number
  843.          * of file descriptors to get the blocks and re-iterate.
  844.          */
  845.         numBlocksNeeded = domainPtr->bitmapBlocks -
  846.         (domainPtr->dataOffset - domainPtr->bitmapOffset);
  847.         numFiles -= numBlocksNeeded * FSDM_FILE_DESC_PER_BLOCK;
  848.     } else if (domainPtr->dataOffset - domainPtr->bitmapOffset >
  849.             domainPtr->bitmapBlocks) {
  850.         int extraBlocks;
  851.         /*
  852.          * There are extra blocks between the end of the file descriptors
  853.          * and the start of the bitmap.  Increase the number of
  854.          * file descriptors and re-iterate.
  855.          */
  856.         extraBlocks = domainPtr->dataOffset - domainPtr->bitmapOffset -
  857.             domainPtr->bitmapBlocks;
  858.         numFiles += extraBlocks * FSDM_FILE_DESC_PER_BLOCK;
  859.     }
  860.     } while (domainPtr->dataOffset - domainPtr->bitmapOffset !=
  861.         domainPtr->bitmapBlocks);
  862.     domainPtr->dataCylinders    = domainPtr->dataBlocks /
  863.                   geoPtr->blocksPerCylinder ;
  864. }
  865.  
  866. /*
  867.  *----------------------------------------------------------------------
  868.  *
  869.  * SetSummaryInfo --
  870.  *
  871.  *    Initialize the summary information for the domain.  It is well
  872.  *    known that this occupies one sector.
  873.  *
  874.  * Results:
  875.  *    A return code.
  876.  *
  877.  * Side effects:
  878.  *    Fill in the summary info.
  879.  *
  880.  *----------------------------------------------------------------------
  881.  */
  882. void
  883. SetSummaryInfo()
  884. {
  885.  
  886.     bzero((Address)summaryPtr, DEV_BYTES_PER_SECTOR);
  887.  
  888.     strcpy(summaryPtr->domainPrefix, "(new domain)");
  889.     /*
  890.      * 4 blocks are already allocated for the root directory.
  891.      */
  892.     summaryPtr->numFreeKbytes = domainPtr->dataBlocks * (FS_BLOCK_SIZE / 1024)
  893.                 - 4;
  894.     /*
  895.      * 3 file descriptors are already used, 0 and 1 are reserved and
  896.      * 2 is for the root.
  897.      */
  898.     summaryPtr->numFreeFileDesc = domainPtr->numFileDesc - 3;
  899.     /*
  900.      * The summary state field is unused.
  901.      */
  902.     summaryPtr->state = 0;
  903.     /*
  904.      * The domain number under which this disk partition is mounted is
  905.      * recorded on disk so servers re-attach disks under the same "name".
  906.      * We set it to the special value so it gets a new number assigned
  907.      * when it is first attached.
  908.      */
  909.     summaryPtr->domainNumber = -1;
  910.     /*
  911.      * The flags field is used to record whether or not the disk has been
  912.      * safely "sync"ed to disk upon shutdown.
  913.      */
  914.     summaryPtr->flags = 0;
  915.     summaryPtr->attachSeconds = 0;
  916.     summaryPtr->detachSeconds = 0;
  917.     summaryPtr->fixCount = 0;
  918. }
  919.  
  920. /*
  921.  *----------------------------------------------------------------------
  922.  *
  923.  * WriteAllFileDescs --
  924.  *
  925.  *    Write out the file descriptor array to disk.
  926.  *
  927.  * Results:
  928.  *    None.
  929.  *
  930.  * Side effects:
  931.  *    None.
  932.  *
  933.  *----------------------------------------------------------------------
  934.  */
  935. void
  936. WriteAllFileDescs()
  937. {
  938.     int                status;
  939.     char            *bitmap;
  940.     char            *block;
  941.     register Fsdm_FileDescriptor    *fileDescPtr;
  942.     register int        index;
  943.  
  944.     bitmap = MakeFileDescBitmap();
  945.     if (!printOnly) {
  946.     status = Disk_BlockWrite(partFID, domainPtr,
  947.                 domainPtr->fdBitmapOffset,
  948.                 domainPtr->fdBitmapBlocks, (Address)bitmap);
  949.     if (status != 0) {
  950.         fprintf(stderr, "WriteAllFileDescs: Could write fd bitmap\n");
  951.         exit(1);
  952.     }
  953.     }
  954.     /*
  955.      * Make the first block of file descriptors.  This contains some
  956.      * canned file descriptors for the root, bad block file, and the
  957.      * lost and found directory.  For (early system) testing an empty file
  958.      * can also be created.
  959.      */
  960.     block = (char *)malloc(FS_BLOCK_SIZE);
  961.     bzero(block, FS_BLOCK_SIZE);
  962.     for (index = 0;
  963.          index < FSDM_FILE_DESC_PER_BLOCK;
  964.      index++ ) {
  965.     fileDescPtr = (Fsdm_FileDescriptor *)((int)block +
  966.                        index * FSDM_MAX_FILE_DESC_SIZE);
  967.     fileDescPtr->magic = FSDM_FD_MAGIC;
  968.     if (index < FSDM_BAD_BLOCK_FILE_NUMBER) {
  969.         fileDescPtr->flags = FSDM_FD_RESERVED;
  970.     } else if (index == FSDM_BAD_BLOCK_FILE_NUMBER) {
  971.         InitDesc(fileDescPtr, FS_FILE, 0, -1, -1, 0, 0, 0700, curTime.tv_sec);
  972.         fileDescPtr->permissions = 0000;
  973.         fileDescPtr->numLinks = 0;
  974.     } else if (index == FSDM_ROOT_FILE_NUMBER) {
  975.         InitDesc(fileDescPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, 0,
  976.             0, 0755, curTime.tv_sec);
  977.         /*
  978.          * Place the data in the first file system block.
  979.          */
  980.         fileDescPtr->direct[0] = 0;
  981.     } else {
  982.         fileDescPtr->flags = FSDM_FD_FREE;
  983.     }
  984.     }
  985.     if (!printOnly) {
  986.     /*
  987.      * Write out the first, specially hand crafted, block of file
  988.      * descriptors.
  989.      */
  990.     status = Disk_BlockWrite(partFID, domainPtr, 
  991.                  domainPtr->fileDescOffset,
  992.                  1, (Address)block);
  993.     if (status != 0) {
  994.         fprintf(stderr, "WriteAllFileDescs: Couldn't write descriptor\n");
  995.         exit(1);
  996.     }
  997.     /*
  998.      * Redo the block for the remaining file descriptors
  999.      */
  1000.     bzero(block, FS_BLOCK_SIZE);
  1001.     for (index = 0;
  1002.          index < FSDM_FILE_DESC_PER_BLOCK;
  1003.          index++ ) {
  1004.         fileDescPtr = (Fsdm_FileDescriptor *)((int)block + index *
  1005.                            FSDM_MAX_FILE_DESC_SIZE);
  1006.         fileDescPtr->magic = FSDM_FD_MAGIC;
  1007.         fileDescPtr->flags = FSDM_FD_FREE;
  1008.     }
  1009.     /*
  1010.      * Write out the remaining file descriptors.
  1011.      */
  1012.     for (index = FSDM_FILE_DESC_PER_BLOCK;
  1013.          index < domainPtr->numFileDesc;
  1014.          index += FSDM_FILE_DESC_PER_BLOCK) {
  1015.         status = Disk_BlockWrite(partFID, domainPtr,
  1016.              domainPtr->fileDescOffset + (index/FSDM_FILE_DESC_PER_BLOCK),
  1017.              1, (Address)block);
  1018.         if (status != 0) {
  1019.         fprintf(stderr, 
  1020.             "WriteAllFileDescs: Couldn't write descriptor (2)\n");
  1021.         exit(1);
  1022.         }
  1023.     }
  1024.     }
  1025. }
  1026.  
  1027.  
  1028. /*
  1029.  *----------------------------------------------------------------------
  1030.  *
  1031.  * MakeFileDescBitmap --
  1032.  *
  1033.  *    Compute out the bitmap for file descriptor array to disk.
  1034.  *
  1035.  * Results:
  1036.  *    None.
  1037.  *
  1038.  * Side effects:
  1039.  *    None.
  1040.  *
  1041.  *----------------------------------------------------------------------
  1042.  */
  1043. char *
  1044. MakeFileDescBitmap()
  1045. {
  1046.     register char    *bitmap;
  1047.     register int    index;
  1048.  
  1049.     /*
  1050.      * Allocate and initialize the bitmap to all 0"s to mean all free.
  1051.      */
  1052.     bitmap = (char *)malloc((unsigned) domainPtr->fdBitmapBlocks *
  1053.                  FS_BLOCK_SIZE);
  1054.     bzero((Address)bitmap, domainPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  1055.  
  1056.     /*
  1057.      * Reserve file descriptors 0, 1, and 2.  File number 0 is not used at 
  1058.      * all in the filesystem.  File number 1 is for the file with bad blocks.
  1059.      * File number 2 (FSDM_ROOT_FILE_NUMBER) is the root directory of the domain.
  1060.      *
  1061.      * IF THIS CHANGES remember to fix SetSummaryInfo
  1062.      */
  1063.     bitmap[0] |= 0xe0;
  1064.  
  1065.     /*
  1066.      * Set the bits in the map at the end that don't correspond to
  1067.      * any existing file descriptors.
  1068.      */
  1069.     index = domainPtr->numFileDesc / BITS_PER_BYTE;
  1070.     if (domainPtr->numFileDesc % BITS_PER_BYTE) {
  1071.     register int bitIndex;
  1072.     /*
  1073.      * Take care the last byte that only has part of its bits set.
  1074.      */
  1075.     for (bitIndex = domainPtr->numFileDesc % BITS_PER_BYTE;
  1076.          bitIndex < BITS_PER_BYTE;
  1077.          bitIndex++) {
  1078.         bitmap[index] |= 1 << ((BITS_PER_BYTE - 1) - bitIndex);
  1079.     }
  1080.     index++;
  1081.     }
  1082.     for ( ; index < domainPtr->fdBitmapBlocks * FS_BLOCK_SIZE; index++) {
  1083.     bitmap[index] = 0xff;
  1084.     }
  1085.  
  1086.     if (printOnly) {
  1087.     Disk_PrintFileDescBitmap(domainPtr, bitmap);
  1088.     }
  1089.     return(bitmap);
  1090. }
  1091.  
  1092. /*
  1093.  *----------------------------------------------------------------------
  1094.  *
  1095.  * WriteAndInitDataBitmap --
  1096.  *
  1097.  *    Write out the bitmap for the data blocks.  This knows that the
  1098.  *    first 4K is allocated to the root directory.
  1099.  *
  1100.  * Results:
  1101.  *    A return code from the writes.
  1102.  *
  1103.  * Side effects:
  1104.  *    Write the bitmap.
  1105.  *
  1106.  *----------------------------------------------------------------------
  1107.  */
  1108. void
  1109. WriteAndInitDataBitmap()
  1110. {
  1111.     int        status;
  1112.     char    *bitmap;
  1113.     int        kbytesPerCyl;
  1114.     int        bitmapBytesPerCyl;
  1115.     int        index;
  1116.  
  1117.     bitmap = (char *)malloc((unsigned) domainPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1118.     bzero(bitmap, domainPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1119.     /*
  1120.      * Set the bit corresponding to the 4K used for the root directory.
  1121.      *   ________
  1122.      *    |0______7|    Bits are numbered like this in a byte.
  1123.      *
  1124.      * IF THIS CHANGES remember to fix SetSummaryInfo()
  1125.      */
  1126.     bitmap[0] |= 0xf0;
  1127.     /*
  1128.      * The bitmap is organized by cylinder.  There are whole number of
  1129.      * bytes in the bitmap for each cylinder.  Each bit in the bitmap
  1130.      * corresponds to 1 kbyte on the disk.
  1131.      */
  1132.     kbytesPerCyl = domainPtr->geometry.blocksPerCylinder * DISK_KBYTES_PER_BLOCK;
  1133.     bitmapBytesPerCyl = (kbytesPerCyl - 1) / BITS_PER_BYTE + 1;
  1134.     if ((kbytesPerCyl % BITS_PER_BYTE) != 0) {
  1135.     /*
  1136.      * There are bits in the last byte of the bitmap for each cylinder
  1137.      * that don't have kbytes behind them.  Set those bits here so
  1138.      * the blocks don't get allocated.
  1139.      */
  1140.     register int extraBits;
  1141.     register int mask;
  1142.  
  1143.     extraBits = kbytesPerCyl % BITS_PER_BYTE;
  1144.     /*
  1145.      * Set up a mask that has the right part filled with 1"s.
  1146.      */
  1147.     mask = 0x0;
  1148.     for ( ; extraBits < BITS_PER_BYTE ; extraBits++) {
  1149.         mask |= 1 << ((BITS_PER_BYTE - 1) - extraBits);
  1150.     }
  1151.     for (index = 0;
  1152.          index < domainPtr->dataBlocks * DISK_KBYTES_PER_BLOCK / BITS_PER_BYTE;
  1153.          index += bitmapBytesPerCyl) {
  1154.         bitmap[index + bitmapBytesPerCyl - 1] |= mask;
  1155.     }
  1156.     }
  1157.     /*
  1158.      * Set the bits in the bitmap that correspond to non-existent cylinders;
  1159.      * the bitmap is allocated a whole number of blocks on the disk
  1160.      * so there are bytes at its end that don't have blocks behind them.
  1161.      */
  1162.  
  1163.     for (index = domainPtr->dataCylinders * bitmapBytesPerCyl;
  1164.      index < domainPtr->bitmapBlocks * FS_BLOCK_SIZE;
  1165.      index++) {
  1166.     bitmap[index] = 0xff;
  1167.     }
  1168.     if (printOnly) {
  1169.     Disk_PrintDataBlockBitmap(domainPtr, bitmap);
  1170.     } else {
  1171.     status = Disk_BlockWrite(partFID, domainPtr, 
  1172.                  domainPtr->bitmapOffset,
  1173.                  domainPtr->bitmapBlocks, (Address)bitmap);
  1174.     if (status != 0) {
  1175.         fprintf(stderr, "WriteAndInitDataBitmap: Couldn't write bitmap\n");
  1176.         exit(status);
  1177.     }
  1178.     }
  1179. }
  1180.  
  1181.  
  1182. /*
  1183.  *----------------------------------------------------------------------
  1184.  *
  1185.  * WriteRootDirectory --
  1186.  *
  1187.  *    Write the data blocks of the root directory.
  1188.  *
  1189.  * Results:
  1190.  *    A return code from the writes.
  1191.  *
  1192.  * Side effects:
  1193.  *    Write the root directory"s data block.
  1194.  *
  1195.  *----------------------------------------------------------------------
  1196.  */
  1197. void
  1198. WriteRootDirectory()
  1199. {
  1200.     int        status;
  1201.     char    *block;
  1202.     Fslcl_DirEntry    *dirEntryPtr;
  1203.     int        offset;
  1204.     int        i;
  1205.  
  1206.     block = (char *)malloc(FS_BLOCK_SIZE);
  1207.     CreateDir(block, FSDM_ROOT_FILE_NUMBER, FSDM_ROOT_FILE_NUMBER);
  1208.  
  1209.     if (printOnly) {
  1210.     printf("Root Directory\n");
  1211.     offset = 0;
  1212.     dirEntryPtr = (Fslcl_DirEntry *)block;
  1213.     Disk_PrintDirEntry(dirEntryPtr);
  1214.     offset += dirEntryPtr->recordLength;
  1215.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  1216.     Disk_PrintDirEntry(dirEntryPtr);
  1217.     } else {
  1218.     /*
  1219.      * This write trounces the data beyond the stuff allocated to
  1220.      * the root directory.  Currently this is ok and is done because
  1221.      * BlockWrite writes whole numbers of filesystem blocks.
  1222.      */
  1223.     status = Disk_BlockWrite(partFID, domainPtr,
  1224.                  domainPtr->dataOffset, 1, block);
  1225.     if (status != 0) {
  1226.         fprintf(stderr, "WriteRootDirectory: Couldn't write directory\n");
  1227.         exit(status);
  1228.     }
  1229.     }
  1230. }
  1231.  
  1232. /*
  1233.  * The 8 partitions, a through h.
  1234.  */
  1235. #define    A_PART    0
  1236. #define B_PART    1
  1237. #define C_PART    2
  1238. #define D_PART    3
  1239. #define E_PART    4
  1240. #define F_PART    5
  1241. #define G_PART    6
  1242. #define H_PART    7
  1243.  
  1244. #define    BUF_SIZE    100
  1245.  
  1246. char        buf[BUF_SIZE];
  1247. char        fullBuf[BUF_SIZE];
  1248.  
  1249.  
  1250. /*
  1251.  *----------------------------------------------------------------------
  1252.  *
  1253.  * ScanDiskTab --
  1254.  *
  1255.  *    Initialize the disk info struct by looking up this disk type in
  1256.  *    the disk table.
  1257.  *
  1258.  * Results:
  1259.  *    A pointer to a disk info struct.
  1260.  *
  1261.  * Side effects:
  1262.  *    Disk info struct malloc'd and initialized.  The disk header will be
  1263.  *    written if is successfully set up.
  1264.  *
  1265.  *----------------------------------------------------------------------
  1266.  */
  1267. Disk_Info *
  1268. ScanDiskTab()
  1269. {
  1270.     FILE        *fp;
  1271.     int            len;
  1272.     char        *bufPtr;
  1273.     int            fullBufLen;
  1274.     Fsdm_DiskPartition    partTable[FSDM_NUM_DISK_PARTS];
  1275.     int            i;
  1276.     int            sectorsPerTrack;
  1277.     int            tracksPerCylinder;
  1278.     int            sectorsPerCylinder;
  1279.     int            numCylinders;
  1280.     Disk_Info        *diskInfoPtr;
  1281.  
  1282.  
  1283.     fp = fopen("/etc/disktab", "r");
  1284.     if (fp == NULL) {
  1285.     perror("/etc/disktab");
  1286.     exit(1);
  1287.     }
  1288.     len = strlen(diskType);
  1289.     /*
  1290.      * Scan until we reach a line that contains the disk type in it.
  1291.      */
  1292.     while (fgets(buf, BUF_SIZE, fp) != NULL) {
  1293.     if (strncmp(diskType, buf, len) == 0 &&
  1294.         buf[len] == '|') {
  1295.         /*
  1296.          * We found the disk type.
  1297.          */
  1298.         break;
  1299.     }
  1300.     }
  1301.     if (strncmp(diskType, buf, len) != 0) {
  1302.     fprintf(stderr, "`%s' not in disktab\n", diskType);
  1303.     exit(1);
  1304.     }
  1305.  
  1306.     fullBufLen = 0;
  1307.     /*
  1308.      * Now cram all of the lines that end in "\" together.
  1309.      */
  1310.     while (1) {
  1311.     for (bufPtr = buf; *bufPtr != '\n' && *bufPtr != '\\'; bufPtr++) {
  1312.         if (*bufPtr != ' ' && *bufPtr != '\t') {
  1313.         fullBuf[fullBufLen] = *bufPtr;
  1314.         fullBufLen++;
  1315.         }
  1316.     }
  1317.     if (*bufPtr == '\n') {
  1318.         fullBuf[fullBufLen] = 0;
  1319.         break;
  1320.     }
  1321.     if (fgets(buf, BUF_SIZE, fp) == NULL) {
  1322.         fprintf(stderr, "Premature EOF\n");
  1323.         exit(1);
  1324.     }
  1325.     }
  1326.     /*
  1327.      * Now build up a partition table.
  1328.      */
  1329.     for (i = 0; i < FSDM_NUM_DISK_PARTS; i++) {
  1330.     partTable[i].firstCylinder = 0;
  1331.     partTable[i].numCylinders = 0;
  1332.     }
  1333.     for (bufPtr = fullBuf; *bufPtr != 0; bufPtr++) {
  1334.     int    partition;
  1335.  
  1336.     if (strncmp(bufPtr, ":ns#", 4) == 0) {
  1337.         bufPtr += 4;
  1338.         sscanf(bufPtr, "%d", §orsPerTrack);
  1339.     } else if (strncmp(bufPtr, ":nt#", 4) == 0) {
  1340.         bufPtr += 4;
  1341.         sscanf(bufPtr, "%d", &tracksPerCylinder);
  1342.     } else if (strncmp(bufPtr, ":nc#", 4) == 0) {
  1343.         bufPtr += 4;
  1344.         sscanf(bufPtr, "%d", &numCylinders);
  1345.     } else if (strncmp(bufPtr, ":p", 2) == 0) {
  1346.         /*
  1347.          * Skip past the ":p".
  1348.          */
  1349.         bufPtr += 2;
  1350.         partition = *bufPtr - 'a';
  1351.         /*
  1352.          * Skip past the partition character and the #.
  1353.          */
  1354.         bufPtr += 2;
  1355.         sscanf(bufPtr, "%d", &partTable[partition].numCylinders);
  1356.     }
  1357.     }
  1358.     /*
  1359.      * Now that we've built up the number of cylinders build up the
  1360.      * cylinder offsets.
  1361.      */
  1362.     sectorsPerCylinder = sectorsPerTrack * tracksPerCylinder;
  1363.     for (i = 0; i < FSDM_NUM_DISK_PARTS; i++) {
  1364.     partTable[i].numCylinders /= sectorsPerCylinder;
  1365.     }
  1366.  
  1367.     partTable[A_PART].firstCylinder = 0;
  1368.     partTable[B_PART].firstCylinder = partTable[A_PART].numCylinders;
  1369.     partTable[C_PART].firstCylinder = 0;
  1370.     partTable[D_PART].firstCylinder = partTable[B_PART].firstCylinder + 
  1371.             partTable[B_PART].numCylinders;
  1372.     partTable[E_PART].firstCylinder = partTable[D_PART].firstCylinder + 
  1373.             partTable[D_PART].numCylinders;
  1374.     partTable[F_PART].firstCylinder = partTable[E_PART].firstCylinder + 
  1375.             partTable[E_PART].numCylinders;
  1376.     partTable[F_PART].numCylinders = 
  1377.             numCylinders - (partTable[E_PART].firstCylinder +
  1378.                     partTable[E_PART].numCylinders);
  1379.     partTable[G_PART].firstCylinder = partTable[B_PART].firstCylinder + 
  1380.             partTable[B_PART].numCylinders;
  1381.     partTable[G_PART].numCylinders = 
  1382.             numCylinders - (partTable[B_PART].firstCylinder +
  1383.                     partTable[B_PART].numCylinders);
  1384.  
  1385.     /*
  1386.      * Print out the partition table.
  1387.      */
  1388.     printf("Sectors-per-track:    %d\n", sectorsPerTrack);
  1389.     printf("Tracks-per-cylinder:    %d\n", tracksPerCylinder);
  1390.     printf("Sectors-per-cylinder:    %d\n", sectorsPerCylinder);
  1391.     printf("Num-cylinders:        %d\n\n", numCylinders);
  1392.     printf("Partition    First-Cylinder        Num-Cylinders\n");
  1393.     for (i = 0; i < FSDM_NUM_DISK_PARTS; i++) {
  1394.     printf("%c        %d            %d\n",
  1395.            'a' + i, partTable[i].firstCylinder, 
  1396.            partTable[i].numCylinders);
  1397.     }
  1398.  
  1399.     /*
  1400.      * Set up a disk header and write it to sector 0.
  1401.      */
  1402.  
  1403.     if (!printOnly) {
  1404.     int        *headerPtr;
  1405.     Fsdm_DiskHeader    header;
  1406.     int        checkSum;
  1407.     int        status;
  1408.  
  1409.     bzero(&header, sizeof(header));
  1410.     strcpy(header.asciiLabel, diskType);
  1411.     header.magic = FSDM_DISK_MAGIC;
  1412.     header.numCylinders = numCylinders;
  1413.     header.numAltCylinders = 0;
  1414.     header.numHeads = tracksPerCylinder;
  1415.     header.numSectors = sectorsPerTrack;
  1416.     header.bootSector = 1;
  1417.     header.numBootSectors = 15;
  1418.     header.summarySector = 17;
  1419.     header.domainSector = 18;
  1420.     header.numDomainSectors = FSDM_NUM_DOMAIN_SECTORS;
  1421.     header.partition = partition;
  1422.     bcopy(partTable, header.map, sizeof(header.map));
  1423.     /*
  1424.      * Compute the checksum.
  1425.      */
  1426.     header.checkSum = FSDM_DISK_MAGIC;
  1427.     checkSum = 0;
  1428.     for (i = 0, headerPtr = (int *)&header; 
  1429.          i < DEV_BYTES_PER_SECTOR; 
  1430.          i += sizeof(int), headerPtr++) {
  1431.         checkSum ^= *headerPtr;
  1432.     }
  1433.     header.checkSum = checkSum;
  1434.     /*
  1435.      * Recompute the checksum and make sure it matches.
  1436.      */
  1437.     checkSum = 0;
  1438.     for (i = 0, headerPtr = (int *)&header; 
  1439.          i < DEV_BYTES_PER_SECTOR; 
  1440.          i += sizeof(int), headerPtr++) {
  1441.         checkSum ^= *headerPtr;
  1442.     }
  1443.     if (checkSum != FSDM_DISK_MAGIC) {
  1444.         fprintf(stderr, "Bad checksum\n");
  1445.         exit(1);
  1446.     }
  1447.  
  1448.     /*
  1449.      * Write out the disk header.  Unless this is a sun.
  1450.      * On suns the disk label is a special format so the
  1451.      * prom can read it.  So we don't mess with it.
  1452.      */
  1453.  
  1454. #if !defined(sun) && !defined(sun3) && !defined(sun4)
  1455.     status = Disk_SectorWrite(partFID, 0, 1, (Address)&header);
  1456.     if (status != 0) {
  1457.         perror("Couldn't write out the disk header");
  1458.         exit(1);
  1459.     }
  1460. #endif
  1461.  
  1462.     }
  1463.  
  1464.  
  1465.     /*
  1466.      * Allocate, initialize and return the disk info struct.
  1467.      */
  1468.     diskInfoPtr = (Disk_Info *)malloc(sizeof(Disk_Info));
  1469.     (void)strcpy(diskInfoPtr->asciiLabel, diskType);
  1470.     diskInfoPtr->bootSector = 1;
  1471.     diskInfoPtr->numBootSectors = 15;
  1472.     diskInfoPtr->summarySector = 17;
  1473.     diskInfoPtr->domainSector = 18;
  1474.     diskInfoPtr->numDomainSectors = FSDM_NUM_DOMAIN_SECTORS;
  1475.     diskInfoPtr->firstCylinder = partTable[partition].firstCylinder;
  1476.     diskInfoPtr->numCylinders = partTable[partition].numCylinders;
  1477.     diskInfoPtr->numHeads = tracksPerCylinder;
  1478.     diskInfoPtr->numSectors = sectorsPerTrack;
  1479.  
  1480.     return(diskInfoPtr);
  1481. }
  1482.  
  1483.  
  1484. /*
  1485.  *----------------------------------------------------------------------
  1486.  *
  1487.  * ReadFileDescBitmap --
  1488.  *
  1489.  *    Read in the file descriptor bitmap.
  1490.  *
  1491.  * Results:
  1492.  *    A pointer to the file descriptor bit map.
  1493.  *
  1494.  * Side effects:
  1495.  *    Memory allocated for the bit map.
  1496.  *
  1497.  *----------------------------------------------------------------------
  1498.  */
  1499. unsigned char *
  1500. ReadFileDescBitmap()
  1501. {
  1502.     register unsigned char *bitmap;
  1503.  
  1504.     /*
  1505.      * Allocate the bitmap.
  1506.      */
  1507.     bitmap = (unsigned char *)malloc(domainPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  1508.     if (Disk_BlockRead(partFID, domainPtr, domainPtr->fdBitmapOffset,
  1509.           domainPtr->fdBitmapBlocks, (Address)bitmap) < 0) {
  1510.     fprintf(stderr, "ReadFileDescBitmap: Read failed");
  1511.     exit(1);
  1512.     }
  1513.     return(bitmap);
  1514. }
  1515.  
  1516.  
  1517. /*
  1518.  *----------------------------------------------------------------------
  1519.  *
  1520.  * WriteFileDescBitmap --
  1521.  *
  1522.  *    Write out the file descriptor bitmap.
  1523.  *
  1524.  * Results:
  1525.  *    None.
  1526.  *
  1527.  * Side effects:
  1528.  *    None.
  1529.  *
  1530.  *----------------------------------------------------------------------
  1531.  */
  1532. void
  1533. WriteFileDescBitmap(bitmap)
  1534.     register unsigned char     *bitmap;    /* Bitmap to write. */
  1535. {
  1536.     if (Disk_BlockWrite(partFID, domainPtr, domainPtr->fdBitmapOffset,
  1537.            domainPtr->fdBitmapBlocks, (Address)bitmap) < 0) {
  1538.     fprintf(stderr, "WriteFileDescBitmap: Write failed");
  1539.     exit(1);
  1540.     }
  1541. }
  1542.  
  1543.  
  1544. /*
  1545.  *----------------------------------------------------------------------
  1546.  *
  1547.  * ReadBitmap --
  1548.  *
  1549.  *    Read the bitmap off disk.
  1550.  *
  1551.  * Results:
  1552.  *    A pointer to the bitmap.
  1553.  *
  1554.  * Side effects:
  1555.  *    Memory allocated for the bit map.
  1556.  *
  1557.  *----------------------------------------------------------------------
  1558.  */
  1559. unsigned char *
  1560. ReadBitmap()
  1561. {
  1562.     unsigned char *bitmap;
  1563.  
  1564.     bitmap = (unsigned char *)malloc(domainPtr->bitmapBlocks * FS_BLOCK_SIZE);
  1565.     if (Disk_BlockRead(partFID, domainPtr, domainPtr->bitmapOffset,
  1566.           domainPtr->bitmapBlocks, (Address) bitmap) < 0) {
  1567.     fprintf(stderr, "ReadBitmap: Read failed");
  1568.     exit(1);
  1569.     }
  1570.     return(bitmap);
  1571. }
  1572.  
  1573.  
  1574. /*
  1575.  *----------------------------------------------------------------------
  1576.  *
  1577.  * WriteBitmap --
  1578.  *
  1579.  *    Write the bitmap to disk.
  1580.  *
  1581.  * Results:
  1582.  *    None.
  1583.  *
  1584.  * Side effects:
  1585.  *    None.
  1586.  *
  1587.  *----------------------------------------------------------------------
  1588.  */
  1589. void
  1590. WriteBitmap(bitmap)
  1591.     unsigned char        *bitmap;    /* Bitmap to write. */
  1592. {
  1593.     if (Disk_BlockWrite(partFID, domainPtr, domainPtr->bitmapOffset,
  1594.            domainPtr->bitmapBlocks, (Address) bitmap) < 0) {
  1595.     fprintf(stderr, "WriteBitmap: Write failed");
  1596.     exit(1);
  1597.     }
  1598. }
  1599.  
  1600.  
  1601. /*
  1602.  *----------------------------------------------------------------------
  1603.  *
  1604.  * ReadFileDesc --
  1605.  *
  1606.  *    Return the given file descriptor.
  1607.  *
  1608.  * Results:
  1609.  *    None.
  1610.  *
  1611.  * Side effects:
  1612.  *    The file descriptor struct is filled in.
  1613.  *
  1614.  *----------------------------------------------------------------------
  1615.  */
  1616. void
  1617. ReadFileDesc(fdNum, fdPtr)
  1618.     int            fdNum;
  1619.     Fsdm_FileDescriptor    *fdPtr;
  1620. {
  1621.     static char        block[FS_BLOCK_SIZE];
  1622.     int            blockNum;
  1623.     int            offset;
  1624.  
  1625.     blockNum = domainPtr->fileDescOffset + fdNum / FSDM_FILE_DESC_PER_BLOCK;
  1626.     offset = (fdNum & (FSDM_FILE_DESC_PER_BLOCK - 1)) * FSDM_MAX_FILE_DESC_SIZE;
  1627.     if (Disk_BlockRead(partFID, domainPtr, blockNum, 1, 
  1628.                (Address) block) < 0) {
  1629.     fprintf(stderr, "ReadFileDesc: Read failed\n");
  1630.     exit(1);
  1631.     }
  1632.     bcopy((Address)&block[offset], (Address)fdPtr, sizeof(Fsdm_FileDescriptor));
  1633. }
  1634.  
  1635.  
  1636. /*
  1637.  *----------------------------------------------------------------------
  1638.  *
  1639.  * WriteFileDesc --
  1640.  *
  1641.  *    Return the given file descriptor.
  1642.  *
  1643.  * Results:
  1644.  *    None.
  1645.  *
  1646.  * Side effects:
  1647.  *    The file descriptor struct is filled in.
  1648.  *
  1649.  *----------------------------------------------------------------------
  1650.  */
  1651. void
  1652. WriteFileDesc(fdNum, fdPtr)
  1653.     int            fdNum;
  1654.     Fsdm_FileDescriptor    *fdPtr;
  1655. {
  1656.     static char        block[FS_BLOCK_SIZE];
  1657.     int            blockNum;
  1658.     int            offset;
  1659.  
  1660.     blockNum = domainPtr->fileDescOffset + fdNum / FSDM_FILE_DESC_PER_BLOCK;
  1661.     offset = (fdNum & (FSDM_FILE_DESC_PER_BLOCK - 1)) * FSDM_MAX_FILE_DESC_SIZE;
  1662.     if (Disk_BlockRead(partFID, domainPtr, blockNum, 1, 
  1663.                (Address) block) < 0) {
  1664.     fprintf(stderr, "WriteFileDesc: Read failed\n");
  1665.     exit(1);
  1666.     }
  1667.     bcopy(fdPtr, (Address)&block[offset], sizeof(Fsdm_FileDescriptor));
  1668.     if (Disk_BlockWrite(partFID, domainPtr, blockNum, 1, 
  1669.                (Address) block) < 0) {
  1670.     fprintf(stderr, "WriteFileDesc: Write failed\n");
  1671.     exit(1);
  1672.     }
  1673. }
  1674.  
  1675. char    fileBlock[FS_BLOCK_SIZE];
  1676. char    indirectBlock[FS_BLOCK_SIZE];
  1677. int    *indIndexPtr = (int *)indirectBlock;
  1678.  
  1679.  
  1680. /*
  1681.  *----------------------------------------------------------------------
  1682.  *
  1683.  * CopyTree --
  1684.  *
  1685.  *    Copy the tree of files in the given directory
  1686.  *    the disk table.
  1687.  *
  1688.  * Results:
  1689.  *    A pointer to a disk info struct.
  1690.  *
  1691.  * Side effects:
  1692.  *    Disk info struct malloc'd and initialized.  The disk header will be
  1693.  *    written if is successfully set up.
  1694.  *
  1695.  *----------------------------------------------------------------------
  1696.  */
  1697. void
  1698. CopyTree(dirName, dirFDNum, dirFDPtr, parentFDNum, createDir, path)
  1699.     char        *dirName;    /* Name of directory to copy. */
  1700.     int            dirFDNum;    /* File number of directory. */
  1701.     Fsdm_FileDescriptor    *dirFDPtr;    /* File descriptor of directory. */
  1702.     int            parentFDNum;    /* File number of parent. */
  1703.     Boolean        createDir;    /* Should create the directory. */
  1704.     char        *path;
  1705. {
  1706.     DIR            *unixDirPtr;
  1707.     Fslcl_DirEntry        *unixDirEntPtr;
  1708.     DirIndexInfo    indexInfo;
  1709.     Fslcl_DirEntry        *spriteDirEntPtr;
  1710.     char        fileName[FS_MAX_NAME_LENGTH + 1];
  1711.     int            newFDNum;
  1712.     Fsdm_FileDescriptor    newFD;
  1713.     Fsdm_FileDescriptor    *newFDPtr;
  1714.     struct    stat    statBuf;
  1715.     int            followLinks;
  1716.     char        pathName[1024];
  1717.  
  1718.     /*
  1719.      * Get our absolute path name so we can get back if we follow a
  1720.      * symbolic link.
  1721.      */
  1722.     getwd(pathName);
  1723.  
  1724.     if (chdir(dirName) < 0) {
  1725.     perror(dirName);
  1726.     exit(1);
  1727.     }
  1728.  
  1729.     /*
  1730.      * Get a pointer to the UNIX directory.
  1731.      */
  1732.     unixDirPtr = opendir(".");
  1733.     if (unixDirPtr == NULL) {
  1734.     fprintf(stderr, "Can't open directory %s\n", dirName);
  1735.     exit(1);
  1736.     }
  1737.     /*
  1738.      * Open the Sprite directory.
  1739.      */
  1740.     spriteDirEntPtr = OpenDir(dirFDPtr, &indexInfo);
  1741.     if (spriteDirEntPtr == (Fslcl_DirEntry *)NULL) {
  1742.     if (chdir(pathName) < 0) {
  1743.         perror(pathName);
  1744.         exit(1);
  1745.     }
  1746.     }
  1747.     /*
  1748.      * See if there is a "follow.links" file in this directory.  If so
  1749.      * we are supposed to follow symbolic links rather than just copying
  1750.      * the links.
  1751.      */
  1752.     if (stat("follow.links", &statBuf) < 0) {
  1753.     followLinks = 0;
  1754.     } else {
  1755.     printf("Following links ...\n");
  1756.     followLinks = 1;
  1757.     }
  1758.     if (createDir) {
  1759.     CreateDir(indexInfo.dirBlock, dirFDNum, parentFDNum);
  1760.     }
  1761.  
  1762.     for (unixDirEntPtr = (Fslcl_DirEntry *)readdir(unixDirPtr);
  1763.        unixDirEntPtr != NULL;
  1764.        unixDirEntPtr = (Fslcl_DirEntry *)readdir(unixDirPtr)) {
  1765.  
  1766.     if (unixDirEntPtr->nameLength == 1 && 
  1767.         strncmp(unixDirEntPtr->fileName, ".", 1) == 0) {
  1768.         continue;
  1769.     }
  1770.     if (unixDirEntPtr->nameLength == 2 && 
  1771.         strncmp(unixDirEntPtr->fileName, "..", 2) == 0) {
  1772.         continue;
  1773.     }
  1774.     strncpy(fileName, unixDirEntPtr->fileName, unixDirEntPtr->nameLength);
  1775.     fileName[unixDirEntPtr->nameLength] = 0;
  1776.     if (followLinks) {
  1777.         if (stat(fileName, &statBuf) < 0) {
  1778.         perror(fileName);
  1779.         exit(1);
  1780.         }
  1781.     } else {
  1782.         if (lstat(fileName, &statBuf) < 0) {
  1783.         perror(fileName);
  1784.         exit(1);
  1785.         }
  1786.     }
  1787.  
  1788.     newFDNum = freeFDNum;
  1789.     freeFDNum++;
  1790.     MarkFDBitmap(newFDNum, fdBitmapPtr);
  1791.     summaryPtr->numFreeFileDesc--;
  1792.     /*
  1793.      * Read out the file descriptor being careful to save it around
  1794.      * if we found the /dev descriptor.
  1795.      */
  1796.     if ((strcmp(fileName, "dev") == 0) &&
  1797.         (dirFDNum == FSDM_ROOT_FILE_NUMBER)) {
  1798.         if (!(statBuf.st_mode & S_GFDIR)) {
  1799.         fprintf(stderr, "dev isn't a directory\n");
  1800.         exit(1);
  1801.         }
  1802.         ReadFileDesc(newFDNum, &devFD);
  1803.         newFDPtr = &devFD;
  1804.         devFDNum = newFDNum;
  1805.         devFDPtr = newFDPtr;
  1806.     } else {
  1807.         ReadFileDesc(newFDNum, &newFD);
  1808.         newFDPtr = &newFD;
  1809.     }
  1810.     spriteDirEntPtr = AddToDirectory(&indexInfo, spriteDirEntPtr,
  1811.                      newFDNum, fileName);
  1812.     if (statBuf.st_mode & S_GFDIR) {
  1813.         char    newPath[FS_MAX_NAME_LENGTH];
  1814.  
  1815.         /*
  1816.          * Increment the current directories link count because once
  1817.          * the child gets created it will point to the parent.
  1818.          */
  1819.         dirFDPtr->numLinks++;
  1820.         /*
  1821.          * Allocate the currently free file descriptor to this directory.
  1822.          */
  1823.         InitDesc(newFDPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, 
  1824.              0, 0, statBuf.st_mode & 07777, statBuf.st_mtime);
  1825.         /*
  1826.          * Give the directory one full block.  The directory will
  1827.          * be initialized by CopyTree when we call it recursively.
  1828.          */
  1829.         newFDPtr->direct[0] = freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  1830.         MarkDataBitmap(domainPtr, cylBitmapPtr, freeBlockNum,
  1831.                FS_FRAGMENTS_PER_BLOCK);
  1832.         freeBlockNum++;
  1833.         sprintf(newPath, "%s%s/", path, fileName);
  1834.         printf("Directory: %s\n", newPath);
  1835.         CopyTree(fileName, newFDNum, newFDPtr, dirFDNum, TRUE, newPath);
  1836.     } else if ((statBuf.st_mode & S_GFMT) == S_GFREG ||
  1837.            (statBuf.st_mode & S_GFMT) == S_GFLNK) {
  1838.         int    fd;
  1839.         int    blockNum;
  1840.         int    toRead;
  1841.         int    len;
  1842.  
  1843.         blockNum = 0;
  1844.         if ((statBuf.st_mode & S_GFMT) == S_GFREG) {
  1845.         printf("File: %s%s\n", path, fileName);
  1846.         InitDesc(newFDPtr, FS_FILE, statBuf.st_size, -1, -1,
  1847.              0, 0, statBuf.st_mode & 07777, statBuf.st_mtime);
  1848.         /*
  1849.          * Copy the file over.
  1850.          */
  1851.         fd = open(fileName, 0);
  1852.         if (fd < 0) {
  1853.             perror(fileName);
  1854.             exit(1);
  1855.         }
  1856.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  1857.         if (len < 0) {
  1858.             perror(fileName);
  1859.             exit(1);
  1860.         }
  1861.         toRead = statBuf.st_size;
  1862.         } else {
  1863.         len = readlink(fileName, fileBlock, FS_BLOCK_SIZE);
  1864.         if (len < 0) {
  1865.             perror(fileName);
  1866.             exit(1);
  1867.         }
  1868.         fileBlock[len] = '\0';
  1869.         InitDesc(newFDPtr, FS_SYMBOLIC_LINK, len + 1, -1, -1, 
  1870.              0, 0, 0777, statBuf.st_mtime);
  1871.         printf("Symbolic link: %s%s -> %s\n", 
  1872.             path, fileName, fileBlock);
  1873.         toRead = len + 1;
  1874.         }
  1875.  
  1876.         while (len > 0) {
  1877.         if (blockNum == FSDM_NUM_DIRECT_BLOCKS) {
  1878.             int    i;
  1879.             int    *intPtr;
  1880.             /*
  1881.              * Must allocate an indirect block.
  1882.              */
  1883.             newFDPtr->indirect[0] =
  1884.             VirtToPhys(freeBlockNum * FS_FRAGMENTS_PER_BLOCK);
  1885.             MarkDataBitmap(domainPtr, cylBitmapPtr, freeBlockNum,
  1886.                    FS_FRAGMENTS_PER_BLOCK);
  1887.             freeBlockNum++;
  1888.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  1889.             for (i = 0, intPtr = (int *)indirectBlock; 
  1890.              i < FS_BLOCK_SIZE / sizeof(int); 
  1891.              i++, intPtr++) {
  1892.              *intPtr = FSDM_NIL_INDEX;
  1893.             }
  1894.         }
  1895.         if (blockNum >= FSDM_NUM_DIRECT_BLOCKS) {
  1896.             indIndexPtr[blockNum - FSDM_NUM_DIRECT_BLOCKS] = 
  1897.                     freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  1898.             MarkDataBitmap(domainPtr, cylBitmapPtr, freeBlockNum,
  1899.                    FS_FRAGMENTS_PER_BLOCK);
  1900.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  1901.         } else {
  1902.             newFDPtr->direct[blockNum] = 
  1903.                     freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  1904.             if (toRead > FS_BLOCK_SIZE) {
  1905.             MarkDataBitmap(domainPtr, cylBitmapPtr, freeBlockNum,
  1906.                        FS_FRAGMENTS_PER_BLOCK);
  1907.             summaryPtr->numFreeKbytes -= FS_FRAGMENTS_PER_BLOCK;
  1908.             } else {
  1909.             MarkDataBitmap(domainPtr, cylBitmapPtr, freeBlockNum,
  1910.                        (toRead - 1) / FS_FRAGMENT_SIZE + 1);
  1911.             summaryPtr->numFreeKbytes -= 
  1912.                     (toRead - 1) / FS_FRAGMENT_SIZE + 1;
  1913.             }
  1914.         }
  1915.         /*
  1916.          * Write the block out to disk.
  1917.          */
  1918.         if (Disk_BlockWrite(partFID, domainPtr, 
  1919.                     domainPtr->dataOffset + freeBlockNum,
  1920.                     1, (Address)fileBlock) != 0) {
  1921.             fprintf(stderr, "Couldn't write file block\n");
  1922.             exit(1);
  1923.         }
  1924.         blockNum++;
  1925.         freeBlockNum++;
  1926.         if ((statBuf.st_mode & S_GFMT) == S_GFLNK) {
  1927.             break;
  1928.         }
  1929.         toRead -= len;
  1930.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  1931.         if (len < 0) {
  1932.             perror(fileName);
  1933.             exit(1);
  1934.         }
  1935.         }
  1936.         if (newFDPtr->indirect[0] != FSDM_NIL_INDEX) {
  1937.         if (Disk_BlockWrite(partFID, domainPtr,
  1938.                 newFDPtr->indirect[0] / FS_FRAGMENTS_PER_BLOCK,
  1939.                 1, (Address)indirectBlock) != 0) {
  1940.             fprintf(stderr, "Couldn't write indirect block\n");
  1941.             exit(1);
  1942.         }
  1943.         }
  1944.         close(fd);
  1945.     } else {
  1946.         fprintf(stderr, "Non file or directory\n");
  1947.         exit(1);
  1948.     }
  1949.     WriteFileDesc(newFDNum, newFDPtr);
  1950.  
  1951.     if (spriteDirEntPtr == (Fslcl_DirEntry *)NULL) {
  1952.         fprintf(stderr, "%s is full\n", dirName);
  1953.         break;
  1954.     }
  1955.     }
  1956.  
  1957.     CloseDir(&indexInfo);
  1958.  
  1959.     if (chdir(pathName) < 0) {
  1960.     perror(pathName);
  1961.     exit(1);
  1962.     }
  1963.     closedir(unixDirPtr);
  1964.     return;
  1965. }
  1966.  
  1967.  
  1968. /*
  1969.  *----------------------------------------------------------------------
  1970.  *
  1971.  * OpenDir --
  1972.  *
  1973.  *    Set up the structure to allow moving through the given directory.
  1974.  *
  1975.  * Results:
  1976.  *    None.
  1977.  *
  1978.  * Side effects:
  1979.  *    The index structure is set up and *dirEntryPtrPtr set to point to
  1980.  *    the first directory entry.
  1981.  *
  1982.  *----------------------------------------------------------------------
  1983.  */
  1984. static Fslcl_DirEntry *
  1985. OpenDir(fdPtr, indexInfoPtr)
  1986.     Fsdm_FileDescriptor    *fdPtr;        /* The file descriptor for the
  1987.                      * directory. */
  1988.     DirIndexInfo     *indexInfoPtr;    /* Index info struct */
  1989. {
  1990.     int            fragsToRead;
  1991.  
  1992.     if (fdPtr->lastByte == -1) {
  1993.     /*
  1994.      * Empty directory.
  1995.      */
  1996.     return((Fslcl_DirEntry *) NULL);
  1997.     } else if ((fdPtr->lastByte + 1) % FSLCL_DIR_BLOCK_SIZE != 0) {
  1998.     fprintf(stderr, "Directory not multiple of directory block size.\n");
  1999.     exit(1);
  2000.     } else if (fdPtr->fileType != FS_DIRECTORY) {
  2001.     fprintf(stderr, "OpenDir: Not a directory\n");
  2002.     return((Fslcl_DirEntry *)NULL);
  2003.     }
  2004.  
  2005.     /*
  2006.      * Initialize the index structure.
  2007.      */
  2008.     indexInfoPtr->fdPtr = fdPtr;
  2009.     indexInfoPtr->blockNum = 0;
  2010.     indexInfoPtr->blockAddr = fdPtr->direct[0] / FS_FRAGMENTS_PER_BLOCK + 
  2011.                   domainPtr->dataOffset;
  2012.     /*
  2013.      * Read in the directory block.
  2014.      */
  2015.     if (fdPtr->lastByte != FS_BLOCK_SIZE - 1) {
  2016.     fprintf(stderr, "We created a directory that's not 4K?\n");
  2017.     exit(1);
  2018.     }
  2019.     if (Disk_BlockRead(partFID, domainPtr,
  2020.                indexInfoPtr->blockAddr,
  2021.                1, indexInfoPtr->dirBlock) < 0) {
  2022.     fprintf(stderr, "OpenDir: Read failed block %d\n",
  2023.             indexInfoPtr->blockAddr);
  2024.     exit(1);
  2025.     } 
  2026.     indexInfoPtr->dirOffset = 0;
  2027.     return((Fslcl_DirEntry *) indexInfoPtr->dirBlock);
  2028. }
  2029.  
  2030.  
  2031. /*
  2032.  *----------------------------------------------------------------------
  2033.  *
  2034.  * NextDirEntry --
  2035.  *
  2036.  *    Return a pointer to the next directory entry.
  2037.  *
  2038.  * Results:
  2039.  *    None.
  2040.  *
  2041.  * Side effects:
  2042.  *    The index structure is modified and *dirEntryPtrPtr set to point
  2043.  *    to the next directory entry.
  2044.  *
  2045.  *----------------------------------------------------------------------
  2046.  */
  2047. Fslcl_DirEntry *
  2048. NextDirEntry(indexInfoPtr, dirEntryPtr)
  2049.     DirIndexInfo     *indexInfoPtr;
  2050.     Fslcl_DirEntry        *dirEntryPtr;
  2051. {
  2052.     indexInfoPtr->dirOffset += dirEntryPtr->recordLength;
  2053.     if (indexInfoPtr->dirOffset < FS_BLOCK_SIZE) {
  2054.     /*
  2055.      * The next directory entry is in the current block.
  2056.      */
  2057.     return((Fslcl_DirEntry *)
  2058.             &(indexInfoPtr->dirBlock[indexInfoPtr->dirOffset]));
  2059.     } else {
  2060.     Fsdm_FileDescriptor    *fdPtr;
  2061.     int            i;
  2062.  
  2063.     printf("Adding new block to directory ...\n");
  2064.  
  2065.     /*
  2066.      * Write out the current block and set up the next one.
  2067.      */
  2068.     if (!printOnly) {
  2069.         if (Disk_BlockWrite(partFID, domainPtr, indexInfoPtr->blockAddr,
  2070.                 1, indexInfoPtr->dirBlock) < 0) {
  2071.         fprintf(stderr, "NextDirEntry: Write failed block %d\n",
  2072.                 indexInfoPtr->blockAddr);
  2073.         exit(1);
  2074.         }
  2075.     }
  2076.     fdPtr = indexInfoPtr->fdPtr;
  2077.     fdPtr->lastByte += FS_BLOCK_SIZE;
  2078.     fdPtr->numKbytes += FS_FRAGMENTS_PER_BLOCK;
  2079.     indexInfoPtr->blockNum++;
  2080.     fdPtr->direct[indexInfoPtr->blockNum] = 
  2081.                 freeBlockNum * FS_FRAGMENTS_PER_BLOCK;
  2082.     MarkDataBitmap(domainPtr, cylBitmapPtr, freeBlockNum,
  2083.                FS_FRAGMENTS_PER_BLOCK);
  2084.     indexInfoPtr->blockAddr = freeBlockNum + domainPtr->dataOffset;
  2085.     freeBlockNum++;
  2086.     for (i = 0, dirEntryPtr = (Fslcl_DirEntry *)indexInfoPtr->dirBlock; 
  2087.          i < FS_BLOCK_SIZE / FSLCL_DIR_BLOCK_SIZE;
  2088.      i++,dirEntryPtr=(Fslcl_DirEntry *)((unsigned)dirEntryPtr+FSLCL_DIR_BLOCK_SIZE)) {
  2089.         dirEntryPtr->fileNumber = 0;
  2090.         dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE;
  2091.         dirEntryPtr->nameLength = 0;
  2092.     }
  2093.     indexInfoPtr->dirOffset = 0;
  2094.     return((Fslcl_DirEntry *) indexInfoPtr->dirBlock);
  2095.     }
  2096. }
  2097.  
  2098.  
  2099. /*
  2100.  *----------------------------------------------------------------------
  2101.  *
  2102.  * CloseDir --
  2103.  *
  2104.  *    Flushes the current directory block to disk, if necessary.
  2105.  *
  2106.  * Results:
  2107.  *    None.
  2108.  *
  2109.  * Side effects:
  2110.  *    The index structure is modified and *dirEntryPtrPtr set to point
  2111.  *    to the next directory entry.
  2112.  *
  2113.  *----------------------------------------------------------------------
  2114.  */
  2115. static void
  2116. CloseDir(indexInfoPtr)
  2117.     DirIndexInfo     *indexInfoPtr;
  2118. {
  2119.  
  2120.     if (!printOnly) {
  2121.     if (Disk_BlockWrite(partFID, domainPtr, indexInfoPtr->blockAddr,
  2122.                 1, indexInfoPtr->dirBlock) < 0) {
  2123.         fprintf(stderr, "CloseDir: Write (2) failed block %d\n",
  2124.                 indexInfoPtr->blockAddr);
  2125.         exit(1);
  2126.     }
  2127.     }
  2128. }
  2129.  
  2130.  
  2131. /*
  2132.  *----------------------------------------------------------------------
  2133.  *
  2134.  * InitDesc --
  2135.  *
  2136.  *    Set up a file descriptor as allocated.
  2137.  *
  2138.  * Results:
  2139.  *    None.
  2140.  *
  2141.  * Side effects:
  2142.  *    File descriptor fields filled in.
  2143.  *
  2144.  *----------------------------------------------------------------------
  2145.  */
  2146. void
  2147. InitDesc(fileDescPtr, fileType, numBytes, devType, devUnit, uid,
  2148.     gid, permissions, time)
  2149.     Fsdm_FileDescriptor    *fileDescPtr;
  2150.     int            fileType;
  2151.     int            numBytes;
  2152.     int            devType;
  2153.     int            devUnit;
  2154.     int            uid;
  2155.     int            gid;
  2156.     int            permissions;
  2157.     int            time;
  2158. {
  2159.     int        index;
  2160.  
  2161.     fileDescPtr->flags = FSDM_FD_ALLOC;
  2162.     fileDescPtr->fileType = fileType;
  2163.     fileDescPtr->permissions = permissions;
  2164.     fileDescPtr->uid = uid;
  2165.     fileDescPtr->gid = gid;
  2166.     fileDescPtr->lastByte = numBytes - 1;
  2167.     fileDescPtr->firstByte = -1;
  2168.     if (fileType == FS_DIRECTORY) {
  2169.     fileDescPtr->numLinks = 2;
  2170.     } else {
  2171.     fileDescPtr->numLinks = 1;
  2172.     }
  2173.     /*
  2174.      * Can't know device information because that depends on
  2175.      * the way the system is configured.
  2176.      */
  2177.     fileDescPtr->devServerID = -1;
  2178.     fileDescPtr->devType = devType;
  2179.     fileDescPtr->devUnit = devUnit;
  2180.  
  2181.     /*
  2182.      * Set the time stamps.  This assumes that universal time,
  2183.      * not local time, is used for time stamps.
  2184.      */
  2185.     fileDescPtr->createTime = time;
  2186.     fileDescPtr->accessTime = 0;
  2187.     fileDescPtr->descModifyTime = time;
  2188.     fileDescPtr->dataModifyTime = time;
  2189.  
  2190.     /*
  2191.      * Place the data in the first filesystem block.
  2192.      */
  2193.     for (index = 0; index < FSDM_NUM_DIRECT_BLOCKS ; index++) {
  2194.     fileDescPtr->direct[index] = FSDM_NIL_INDEX;
  2195.     }
  2196.     for (index = 0; index < FSDM_NUM_INDIRECT_BLOCKS ; index++) {
  2197.     fileDescPtr->indirect[index] = FSDM_NIL_INDEX;
  2198.     }
  2199.     if (numBytes > 0) {
  2200.     int    numBlocks;
  2201.  
  2202.     numBlocks = (numBytes - 1) / FS_BLOCK_SIZE + 1;
  2203.     if (numBlocks > FSDM_NUM_DIRECT_BLOCKS) {
  2204.         fileDescPtr->numKbytes = (numBlocks + 1) * (FS_BLOCK_SIZE / 1024);
  2205.     } else {
  2206.         fileDescPtr->numKbytes = (numBytes + 1023) / 1024;
  2207.     }
  2208.     } else {
  2209.     fileDescPtr->numKbytes = 0;
  2210.     }
  2211.  
  2212.     fileDescPtr->version = 1;
  2213. }
  2214.  
  2215. int fragMasks[FS_FRAGMENTS_PER_BLOCK + 1] = {0x0, 0x08, 0x0c, 0x0e, 0x0f};
  2216.  
  2217.  
  2218. /*
  2219.  *----------------------------------------------------------------------
  2220.  *
  2221.  * MarkDataBitmap --
  2222.  *
  2223.  *    Mark the appropriate bits in the data block bitmap.
  2224.  *
  2225.  * Results:
  2226.  *    None.
  2227.  *
  2228.  * Side effects:
  2229.  *    Data block marked.
  2230.  *
  2231.  *----------------------------------------------------------------------
  2232.  */
  2233. void
  2234. MarkDataBitmap(domainPtr, cylBitmapPtr, blockNum, numFrags)
  2235.     Fsdm_DomainHeader    *domainPtr;
  2236.     unsigned char    *cylBitmapPtr;
  2237.     int            blockNum;
  2238.     int            numFrags;
  2239. {
  2240.     unsigned char    *bitmapPtr;
  2241.  
  2242.     bitmapPtr = GetBitmapPtr(domainPtr, cylBitmapPtr, blockNum);
  2243.     if ((blockNum % domainPtr->geometry.blocksPerCylinder) & 0x1) {
  2244.     *bitmapPtr |= fragMasks[numFrags];
  2245.     } else {
  2246.     *bitmapPtr |= fragMasks[numFrags] << 4;
  2247.     }
  2248. }
  2249.  
  2250.  
  2251.  
  2252. /*
  2253.  *----------------------------------------------------------------------
  2254.  *
  2255.  * CreateDir --
  2256.  *
  2257.  *    Create a directory out of a single file system block.
  2258.  *
  2259.  * Results:
  2260.  *    None.
  2261.  *
  2262.  * Side effects:
  2263.  *    File system block set up as a directory.
  2264.  *
  2265.  *----------------------------------------------------------------------
  2266.  */
  2267. void
  2268. CreateDir(block, dot, dotDot)
  2269.     Address    block;        /* Block to create directory in. */
  2270.     int        dot;        /* File number of directory. */
  2271.     int        dotDot;        /* File number of parent. */
  2272. {
  2273.     Fslcl_DirEntry    *dirEntryPtr;
  2274.     char    *fileName;
  2275.     int        offset;
  2276.     int        length;
  2277.     int        i;
  2278.  
  2279.     dirEntryPtr = (Fslcl_DirEntry *)block;
  2280.     fileName = ".";
  2281.     length = strlen(fileName);
  2282.     dirEntryPtr->fileNumber = dot;
  2283.     dirEntryPtr->recordLength = Fslcl_DirRecLength(length);
  2284.     dirEntryPtr->nameLength = length;
  2285.     strcpy(dirEntryPtr->fileName, fileName);
  2286.     offset = dirEntryPtr->recordLength;
  2287.  
  2288.     dirEntryPtr = (Fslcl_DirEntry *)((int)block + offset);
  2289.     fileName = "..";
  2290.     length = strlen(fileName);
  2291.     dirEntryPtr->fileNumber = dotDot;
  2292.     dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE - offset;
  2293.     dirEntryPtr->nameLength = length;
  2294.     strcpy(dirEntryPtr->fileName, fileName);
  2295.     /*
  2296.      * Fill out the rest of the directory with empty blocks.
  2297.      */
  2298.     for (dirEntryPtr = (Fslcl_DirEntry *)&block[FSLCL_DIR_BLOCK_SIZE], i = 1; 
  2299.      i < FS_BLOCK_SIZE / FSLCL_DIR_BLOCK_SIZE;
  2300.      i++,dirEntryPtr=(Fslcl_DirEntry *)((int)dirEntryPtr + FSLCL_DIR_BLOCK_SIZE)) {
  2301.      dirEntryPtr->fileNumber = 0;
  2302.      dirEntryPtr->recordLength = FSLCL_DIR_BLOCK_SIZE;
  2303.      dirEntryPtr->nameLength = 0;
  2304.     }
  2305. }
  2306.  
  2307.  
  2308. /*
  2309.  *----------------------------------------------------------------------
  2310.  *
  2311.  * AddToDirectory --
  2312.  *
  2313.  *    Add the file descriptor to a directory.  
  2314.  *
  2315.  * Results:
  2316.  *    None.
  2317.  *
  2318.  * Side effects:
  2319.  *    The directory is modified to contain the orphaned file.
  2320.  *
  2321.  *----------------------------------------------------------------------
  2322.  */
  2323. Fslcl_DirEntry *
  2324. AddToDirectory(dirIndexPtr, dirEntryPtr, fileNumber, fileName)
  2325.     DirIndexInfo    *dirIndexPtr;
  2326.     Fslcl_DirEntry        *dirEntryPtr;
  2327.     int             fileNumber;
  2328.     char         *fileName;
  2329. {
  2330.     int             nameLength;
  2331.     int             recordLength;
  2332.     int             leftOver;
  2333.     int            oldRecLength;
  2334.  
  2335.     nameLength = strlen(fileName);
  2336.     recordLength = Fslcl_DirRecLength(nameLength);
  2337.  
  2338.     while (dirEntryPtr != (Fslcl_DirEntry *) NULL) {
  2339.     if (dirEntryPtr->fileNumber != 0) {
  2340.         oldRecLength = Fslcl_DirRecLength(dirEntryPtr->nameLength);
  2341.         leftOver = dirEntryPtr->recordLength - oldRecLength;
  2342.         if (leftOver >= recordLength) {
  2343.         dirEntryPtr->recordLength = oldRecLength;
  2344.         dirEntryPtr = 
  2345.             (Fslcl_DirEntry *) ((int) dirEntryPtr + oldRecLength);
  2346.         dirEntryPtr->recordLength = leftOver;
  2347.         dirIndexPtr->dirOffset += oldRecLength;
  2348.         } else {
  2349.         dirEntryPtr = NextDirEntry(dirIndexPtr, dirEntryPtr);
  2350.         continue;
  2351.         }
  2352.     } else if (dirEntryPtr->recordLength < recordLength) {
  2353.         dirEntryPtr = NextDirEntry(dirIndexPtr, dirEntryPtr);
  2354.         continue;
  2355.     }
  2356.  
  2357.     dirEntryPtr->fileNumber = fileNumber;
  2358.     dirEntryPtr->nameLength = nameLength;
  2359.     (void)strcpy(dirEntryPtr->fileName, fileName);
  2360.     leftOver = dirEntryPtr->recordLength - recordLength;
  2361.     if (leftOver > FSLCL_DIR_ENTRY_HEADER) {
  2362.         dirEntryPtr->recordLength = recordLength;
  2363.         dirEntryPtr =(Fslcl_DirEntry *) ((int) dirEntryPtr + recordLength);
  2364.         dirEntryPtr->fileNumber = 0;
  2365.         dirEntryPtr->recordLength = leftOver;
  2366.         dirIndexPtr->dirOffset += recordLength;
  2367.     } else {
  2368.         dirEntryPtr = NextDirEntry(dirIndexPtr, dirEntryPtr);
  2369.     }
  2370.     return(dirEntryPtr);
  2371.     }
  2372.  
  2373.     fprintf(stderr, "Directory full.\n");
  2374.     exit(1);
  2375. }
  2376.  
  2377.  
  2378. /*
  2379.  *----------------------------------------------------------------------
  2380.  *
  2381.  * MakeDevices --
  2382.  *
  2383.  *    Add devices to the dev directory.
  2384.  *
  2385.  * Results:
  2386.  *    None.
  2387.  *
  2388.  * Side effects:
  2389.  *    Devices added to the dev directory.
  2390.  *
  2391.  *----------------------------------------------------------------------
  2392.  */
  2393. void
  2394. MakeDevices()
  2395. {
  2396.     FILE        *fp;
  2397.     Fslcl_DirEntry        *dirEntryPtr;
  2398.     DirIndexInfo    indexInfo;
  2399.     char        fileName[FS_MAX_NAME_LENGTH];
  2400.     int            devType;
  2401.     int            devUnit;
  2402.     int            devPermissions;
  2403.     char        buf[FS_MAX_NAME_LENGTH];
  2404.     Fsdm_FileDescriptor    fileFD;
  2405.  
  2406.     fp = fopen(devFileName, "r");
  2407.     if (fp == NULL) {
  2408.     perror(devFileName);
  2409.     exit(1);
  2410.     }
  2411.  
  2412.     dirEntryPtr = OpenDir(devFDPtr, &indexInfo);
  2413.     if (dirEntryPtr == (Fslcl_DirEntry *)NULL) {
  2414.     fprintf(stderr, "MakeDevices: Dev is bogus\n");
  2415.     exit(1);
  2416.     }
  2417.     while (fgets(buf, FS_MAX_NAME_LENGTH, fp) != NULL) {
  2418.     if (sscanf(buf, "%s %d %d %o", fileName, &devType, &devUnit,
  2419.         &devPermissions) != 4) {
  2420.         continue;
  2421.     }
  2422.     MarkFDBitmap(freeFDNum, fdBitmapPtr);
  2423.     ReadFileDesc(freeFDNum, &fileFD);
  2424.     InitDesc(&fileFD, FS_DEVICE, 0, devType, devUnit, 0, 0,
  2425.         devPermissions, curTime.tv_sec);
  2426.     dirEntryPtr = AddToDirectory(&indexInfo, dirEntryPtr, freeFDNum,
  2427.                      fileName);
  2428.     if (!printOnly) {
  2429.         WriteFileDesc(freeFDNum, &fileFD);
  2430.     }
  2431.     printf("Device: %s, %d, %d 0%o\n",
  2432.         fileName, devType, devUnit, devPermissions);
  2433.  
  2434.     summaryPtr->numFreeFileDesc--;
  2435.     freeFDNum++;
  2436.     if (dirEntryPtr == (Fslcl_DirEntry *)NULL) {
  2437.         fprintf(stderr, "MakeDevices: dev directory is full\n");
  2438.         break;
  2439.     }
  2440.     }
  2441.     CloseDir(&indexInfo);
  2442. }
  2443.  
  2444. #if 0
  2445. /*
  2446.  *----------------------------------------------------------------------
  2447.  *
  2448.  * CopySuperBlock --
  2449.  *
  2450.  *    Copy the super block from the first sector of the disk to
  2451.  *    the first sector of the partition being formatted.
  2452.  *
  2453.  * Results:
  2454.  *    A return code from the I/O.
  2455.  *
  2456.  * Side effects:
  2457.  *    Writes on the zero'th sector of the partition.
  2458.  *
  2459.  *----------------------------------------------------------------------
  2460.  */
  2461. ReturnStatus
  2462. CopySuperBlock(firstPartFID, partFID)
  2463.     int firstPartFID;
  2464.     int partFID;
  2465. {
  2466.     ReturnStatus status;
  2467.     char *block;
  2468.  
  2469.     block = (char *)malloc(DEV_BYTES_PER_SECTOR);
  2470.  
  2471.     status = Disk_SectorRead(firstPartFID, 0, 1, block);
  2472.     if (status != SUCCESS) {
  2473.     return(status);
  2474.     }
  2475.     status = Disk_SectorWrite(partFID, 0, 1, block);
  2476.     return(status);
  2477. }
  2478. #endif
  2479. @
  2480.  
  2481.  
  2482. 1.13
  2483. log
  2484. @Preserve creation times on files, and print out error message
  2485. if a file can't be read.
  2486. @
  2487. text
  2488. @d38 1
  2489. a38 1
  2490. static char rcsid[] = "$Header: /sprite/src/admin/fsinstall/RCS/fsmake.c,v 1.12 89/12/13 14:06:45 rab Exp Locker: ouster $ SPRITE (Berkeley)";
  2491. d83 1
  2492. d106 2
  2493. d308 1
  2494. a308 1
  2495.     if (diskInfoPtr == NULL) {
  2496. @
  2497.  
  2498.  
  2499. 1.12
  2500. log
  2501. @Fixed problem with reading first sector.
  2502. @
  2503. text
  2504. @d38 1
  2505. a38 1
  2506. static char rcsid[] = "$Header: /sprite/src/admin/fsinstall/RCS/fsmake.c,v 1.11 89/11/29 16:49:52 ouster Exp Locker: rab $ SPRITE (Berkeley)";
  2507. d52 1
  2508. d126 6
  2509. d251 2
  2510. d880 1
  2511. a880 1
  2512.         InitDesc(fileDescPtr, FS_FILE, 0, -1, -1, 0, 0, 0700);
  2513. d885 1
  2514. a885 1
  2515.             0, 0755);
  2516. d1733 1
  2517. a1733 1
  2518.              0, 0, statBuf.st_mode & 07777);
  2519. d1756 1
  2520. a1756 1
  2521.              0, 0, statBuf.st_mode & 07777);
  2522. d1766 4
  2523. d1779 1
  2524. a1779 1
  2525.              0, 0, 0777);
  2526. d1840 4
  2527. d2057 1
  2528. a2057 1
  2529.     gid, permissions)
  2530. d2066 1
  2531. a2067 1
  2532.     Time    time;
  2533. d2091 2
  2534. a2092 2
  2535.      * Set the time stamps.  This assumes that universal time, not local
  2536.      * time, is used for time stamps.
  2537. d2094 1
  2538. a2094 2
  2539.     gettimeofday(&time, NULL);
  2540.     fileDescPtr->createTime = time.seconds;
  2541. d2096 2
  2542. a2097 2
  2543.     fileDescPtr->descModifyTime = time.seconds;
  2544.     fileDescPtr->dataModifyTime = time.seconds;
  2545. d2334 1
  2546. a2334 1
  2547.         devPermissions);
  2548. a2387 1
  2549.  
  2550. @
  2551.  
  2552.  
  2553. 1.11
  2554. log
  2555. @Always create things as root.  Also, read permissions from dev_file.
  2556. @
  2557. text
  2558. @d38 1
  2559. a38 1
  2560. static char rcsid[] = "$Header: fsmake.c,v 1.1 89/11/29 13:43:45 ouster Locked $ SPRITE (Berkeley)";
  2561. d51 2
  2562. d200 15
  2563. d241 2
  2564. d259 2
  2565. d294 25
  2566. a318 3
  2567.     /*
  2568.      * Read the copy of the super block at the beginning of the partition
  2569.      * to find out basic disk geometry and where to write the domain header.
  2570. d320 5
  2571. a324 14
  2572. #ifdef notdef
  2573.     diskInfoPtr = Disk_ReadDiskInfo(partFID, partition);
  2574. #endif
  2575.     diskInfoPtr = (Disk_Info *)NULL;
  2576.     if (diskInfoPtr == (Disk_Info *)NULL) {
  2577.     if (diskType != NULL) {
  2578.         /*
  2579.          * See if we can find the information in /etc/disktab.
  2580.          */
  2581.         diskInfoPtr = ScanDiskTab();
  2582.     }
  2583.     if (diskInfoPtr == (Disk_Info *)NULL) {
  2584.         fprintf(stderr,"MakeFilesystem: Unable to read super block.\n");
  2585.         return(1);
  2586. d326 15
  2587. a341 1
  2588.  
  2589. d349 1
  2590. d362 1
  2591. d387 2
  2592. a388 2
  2593.     CopyTree(dirName, FSDM_ROOT_FILE_NUMBER, &rootDesc, FSDM_ROOT_FILE_NUMBER,
  2594.          FALSE, "/");
  2595. d398 1
  2596. d2096 1
  2597. a2096 1
  2598.     if (numBlocks >= FSDM_NUM_DIRECT_BLOCKS) {
  2599. d2336 37
  2600. @
  2601.  
  2602.  
  2603. 1.10
  2604. log
  2605. @Make sure dev directory is the root dev directory.
  2606. @
  2607. text
  2608. @d38 1
  2609. a38 1
  2610. static char rcsid[] = "$Header: /sprite/src/admin/fsinstall/RCS/fsmake.c,v 1.9 89/11/27 21:44:16 jhh Exp Locker: rab $ SPRITE (Berkeley)";
  2611. d55 1
  2612. a55 1
  2613. #ifdef sprite
  2614. d67 1
  2615. a67 1
  2616. Boolean printOnly = TRUE;    /* Stop after computing the domain header
  2617. d75 1
  2618. a75 1
  2619. int  spriteID = 0;        /* This machines sprite id. */
  2620. d91 1
  2621. a91 1
  2622.     "Test: print results, don't write disk (TRUE)"},
  2623. d93 1
  2624. a93 1
  2625.     "Write the disk (FALSE)"},
  2626. d820 1
  2627. a820 1
  2628.         InitDesc(fileDescPtr, FS_FILE, 0, -1, -1, 0, 0);
  2629. d824 2
  2630. a825 1
  2631.         InitDesc(fileDescPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1, 0, 0);
  2632. d1673 1
  2633. a1673 1
  2634.              statBuf.st_uid, statBuf.st_gid);
  2635. d1696 1
  2636. a1696 1
  2637.              statBuf.st_uid, statBuf.st_gid);
  2638. d1715 1
  2639. a1715 1
  2640.              statBuf.st_uid, statBuf.st_gid);
  2641. d1988 2
  2642. a1989 1
  2643. InitDesc(fileDescPtr, fileType, numBytes, devType, devUnit, uid, gid)
  2644. d1997 1
  2645. d2004 1
  2646. a2004 1
  2647.     fileDescPtr->permissions = 0755;
  2648. d2244 1
  2649. d2260 2
  2650. a2261 1
  2651.     if (sscanf(buf, "%s %d %d", fileName, &devType, &devUnit) != 3) {
  2652. d2266 2
  2653. a2267 1
  2654.     InitDesc(&fileFD, FS_DEVICE, 0, devType, devUnit, 0, 0);
  2655. d2273 2
  2656. a2274 2
  2657.     printf("Device: %s, %d, %d\n",
  2658.         fileName, devType, devUnit);
  2659. @
  2660.  
  2661.  
  2662. 1.9
  2663. log
  2664. @*** empty log message ***
  2665. @
  2666. text
  2667. @d38 1
  2668. a38 1
  2669. static char rcsid[] = "$Header: /user2/rab/fsinstall/RCS/fsmake.c,v 1.6 89/06/19 13:18:14 mnelson Exp Locker: rab $ SPRITE (Berkeley)";
  2670. d1644 2
  2671. a1645 1
  2672.     if (strcmp(fileName, "dev") == 0) {
  2673. @
  2674.  
  2675.  
  2676. 1.8
  2677. log
  2678. @*** empty log message ***
  2679. @
  2680. text
  2681. @d2042 1
  2682. a2042 1
  2683.         fileDescPtr->numKbytes = numBlocks * (FS_BLOCK_SIZE / 1024);
  2684. @
  2685.  
  2686.  
  2687. 1.7
  2688. log
  2689. @*** empty log message ***
  2690. @
  2691. text
  2692. @d1149 5
  2693. d1297 3
  2694. a1299 1
  2695.      * Write out the disk header.
  2696. d1301 2
  2697. d1308 2
  2698. @
  2699.  
  2700.  
  2701. 1.6
  2702. log
  2703. @Now can handle directories larger than 4K.
  2704. @
  2705. text
  2706. @d38 2
  2707. a39 2
  2708. static char rcsid[] = "$Header: fsmake.c,v 1.5 89/05/19 17:40:11 mnelson Locked $ SPRITE (Berkeley)";
  2709. #endif not lint
  2710. d55 7
  2711. d109 1
  2712. a109 1
  2713.     FsFileDescriptor *fdPtr;                  /* The file descriptor being
  2714. d137 4
  2715. a140 4
  2716. FsDirEntry    *OpenDir();
  2717. FsDirEntry    *NextDirEntry();
  2718. void        CloseDir();
  2719. FsDirEntry    *AddToDirectory();
  2720. d178 1
  2721. a178 1
  2722. FsFileDescriptor    devFD;        /* The file descriptor for the dev
  2723. d180 1
  2724. a180 1
  2725. FsFileDescriptor    *devFDPtr;    /* Pointer to the file descriptor for
  2726. d186 1
  2727. a186 1
  2728. FsDomainHeader         *domainPtr;    /* The domain the we are initializing.*/
  2729. d191 1
  2730. a191 1
  2731. FsSummaryInfo         *summaryPtr;    /* Summary information for the domain.*/
  2732. d294 1
  2733. a294 1
  2734.     domainPtr = (FsDomainHeader *)
  2735. d309 1
  2736. a309 1
  2737.     summaryPtr = (FsSummaryInfo *) malloc(DEV_BYTES_PER_SECTOR);
  2738. d330 1
  2739. a330 1
  2740.     FsFileDescriptor    rootDesc;
  2741. d336 2
  2742. a337 2
  2743.     ReadFileDesc(FS_ROOT_FILE_NUMBER, &rootDesc);
  2744.     CopyTree(dirName, FS_ROOT_FILE_NUMBER, &rootDesc, FS_ROOT_FILE_NUMBER,
  2745. d339 1
  2746. a339 1
  2747.     WriteFileDesc(FS_ROOT_FILE_NUMBER, &rootDesc);
  2748. d385 1
  2749. a385 1
  2750.     register FsGeometry *geoPtr;
  2751. d387 1
  2752. a387 1
  2753.     domainPtr->magic = FS_DOMAIN_MAGIC;
  2754. d433 1
  2755. a433 1
  2756.     register FsGeometry    *geoPtr;    /* Fancy geometry information */
  2757. d566 1
  2758. a566 1
  2759.         for (index = numBlocks; index < FS_MAX_ROT_POSITIONS; index++){
  2760. d591 1
  2761. a591 1
  2762.     for (index = 0 ; index < FS_MAX_ROT_POSITIONS ; index++) {
  2763. d620 1
  2764. a620 1
  2765.     register FsGeometry *geoPtr;
  2766. d656 1
  2767. a656 1
  2768.     numFiles          &= ~(FS_FILE_DESC_PER_BLOCK-1);
  2769. d667 2
  2770. a668 2
  2771.     numBlocks          -= numFiles / FS_FILE_DESC_PER_BLOCK;
  2772.     offset              += numFiles / FS_FILE_DESC_PER_BLOCK;
  2773. d696 1
  2774. a696 1
  2775.         numFiles -= numBlocksNeeded * FS_FILE_DESC_PER_BLOCK;
  2776. d707 1
  2777. a707 1
  2778.         numFiles += extraBlocks * FS_FILE_DESC_PER_BLOCK;
  2779. d790 1
  2780. a790 1
  2781.     register FsFileDescriptor    *fileDescPtr;
  2782. d812 1
  2783. a812 1
  2784.          index < FS_FILE_DESC_PER_BLOCK;
  2785. d814 6
  2786. a819 6
  2787.     fileDescPtr = (FsFileDescriptor *)((int)block +
  2788.                        index * FS_MAX_FILE_DESC_SIZE);
  2789.     fileDescPtr->magic = FS_FD_MAGIC;
  2790.     if (index < FS_BAD_BLOCK_FILE_NUMBER) {
  2791.         fileDescPtr->flags = FS_FD_RESERVED;
  2792.     } else if (index == FS_BAD_BLOCK_FILE_NUMBER) {
  2793. d823 1
  2794. a823 1
  2795.     } else if (index == FS_ROOT_FILE_NUMBER) {
  2796. d830 1
  2797. a830 1
  2798.         fileDescPtr->flags = FS_FD_FREE;
  2799. d850 1
  2800. a850 1
  2801.          index < FS_FILE_DESC_PER_BLOCK;
  2802. d852 4
  2803. a855 4
  2804.         fileDescPtr = (FsFileDescriptor *)((int)block + index *
  2805.                            FS_MAX_FILE_DESC_SIZE);
  2806.         fileDescPtr->magic = FS_FD_MAGIC;
  2807.         fileDescPtr->flags = FS_FD_FREE;
  2808. d860 1
  2809. a860 1
  2810.     for (index = FS_FILE_DESC_PER_BLOCK;
  2811. d862 1
  2812. a862 1
  2813.          index += FS_FILE_DESC_PER_BLOCK) {
  2814. d864 1
  2815. a864 1
  2816.              domainPtr->fileDescOffset + (index/FS_FILE_DESC_PER_BLOCK),
  2817. d907 1
  2818. a907 1
  2819.      * File number 2 (FS_ROOT_FILE_NUMBER) is the root directory of the domain.
  2820. d1050 1
  2821. a1050 1
  2822.     FsDirEntry    *dirEntryPtr;
  2823. d1055 1
  2824. a1055 1
  2825.     CreateDir(block, FS_ROOT_FILE_NUMBER, FS_ROOT_FILE_NUMBER);
  2826. d1060 1
  2827. a1060 1
  2828.     dirEntryPtr = (FsDirEntry *)block;
  2829. d1063 1
  2830. a1063 1
  2831.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  2832. d1122 1
  2833. a1122 1
  2834.     FsDiskPartition    partTable[FS_NUM_DISK_PARTS];
  2835. d1172 1
  2836. a1172 1
  2837.     for (i = 0; i < FS_NUM_DISK_PARTS; i++) {
  2838. d1206 1
  2839. a1206 1
  2840.     for (i = 0; i < FS_NUM_DISK_PARTS; i++) {
  2841. d1236 1
  2842. a1236 1
  2843.     for (i = 0; i < FS_NUM_DISK_PARTS; i++) {
  2844. d1248 1
  2845. a1248 1
  2846.     FsDiskHeader    header;
  2847. d1254 1
  2848. a1254 1
  2849.     header.magic = FS_DISK_MAGIC;
  2850. d1263 1
  2851. a1263 1
  2852.     header.numDomainSectors = FS_NUM_DOMAIN_SECTORS;
  2853. d1269 1
  2854. a1269 1
  2855.     header.checkSum = FS_DISK_MAGIC;
  2856. d1286 1
  2857. a1286 1
  2858.     if (checkSum != FS_DISK_MAGIC) {
  2859. d1311 1
  2860. a1311 1
  2861.     diskInfoPtr->numDomainSectors = FS_NUM_DOMAIN_SECTORS;
  2862. d1456 1
  2863. a1456 1
  2864.     FsFileDescriptor    *fdPtr;
  2865. d1462 2
  2866. a1463 2
  2867.     blockNum = domainPtr->fileDescOffset + fdNum / FS_FILE_DESC_PER_BLOCK;
  2868.     offset = (fdNum & (FS_FILE_DESC_PER_BLOCK - 1)) * FS_MAX_FILE_DESC_SIZE;
  2869. d1469 1
  2870. a1469 1
  2871.     bcopy((Address)&block[offset], (Address)fdPtr, sizeof(FsFileDescriptor));
  2872. d1491 1
  2873. a1491 1
  2874.     FsFileDescriptor    *fdPtr;
  2875. d1497 2
  2876. a1498 2
  2877.     blockNum = domainPtr->fileDescOffset + fdNum / FS_FILE_DESC_PER_BLOCK;
  2878.     offset = (fdNum & (FS_FILE_DESC_PER_BLOCK - 1)) * FS_MAX_FILE_DESC_SIZE;
  2879. d1504 1
  2880. a1504 1
  2881.     bcopy(fdPtr, (Address)&block[offset], sizeof(FsFileDescriptor));
  2882. d1538 1
  2883. a1538 1
  2884.     FsFileDescriptor    *dirFDPtr;    /* File descriptor of directory. */
  2885. d1544 1
  2886. a1544 1
  2887.     FsDirEntry        *unixDirEntPtr;
  2888. d1546 1
  2889. a1546 1
  2890.     FsDirEntry        *spriteDirEntPtr;
  2891. d1549 2
  2892. a1550 2
  2893.     FsFileDescriptor    newFD;
  2894.     FsFileDescriptor    *newFDPtr;
  2895. d1559 1
  2896. a1559 1
  2897.     getcwd(pathName, 1024);
  2898. d1578 1
  2899. a1578 1
  2900.     if (spriteDirEntPtr == (FsDirEntry *)NULL) {
  2901. d1599 1
  2902. a1599 1
  2903.     for (unixDirEntPtr = (FsDirEntry *)readdir(unixDirPtr);
  2904. d1601 1
  2905. a1601 1
  2906.        unixDirEntPtr = (FsDirEntry *)readdir(unixDirPtr)) {
  2907. d1709 1
  2908. a1709 1
  2909.         if (blockNum == FS_NUM_DIRECT_BLOCKS) {
  2910. d1724 1
  2911. a1724 1
  2912.              *intPtr = FS_NIL_INDEX;
  2913. d1727 2
  2914. a1728 2
  2915.         if (blockNum >= FS_NUM_DIRECT_BLOCKS) {
  2916.             indIndexPtr[blockNum - FS_NUM_DIRECT_BLOCKS] = 
  2917. d1764 1
  2918. a1764 1
  2919.         if (newFDPtr->indirect[0] != FS_NIL_INDEX) {
  2920. d1779 1
  2921. a1779 1
  2922.     if (spriteDirEntPtr == (FsDirEntry *)NULL) {
  2923. d1791 2
  2924. d1812 1
  2925. a1812 1
  2926. static FsDirEntry *
  2927. d1814 1
  2928. a1814 1
  2929.     FsFileDescriptor    *fdPtr;        /* The file descriptor for the
  2930. d1824 2
  2931. a1825 2
  2932.     return((FsDirEntry *) NULL);
  2933.     } else if ((fdPtr->lastByte + 1) % FS_DIR_BLOCK_SIZE != 0) {
  2934. d1830 1
  2935. a1830 1
  2936.     return((FsDirEntry *)NULL);
  2937. d1855 1
  2938. a1855 1
  2939.     return((FsDirEntry *) indexInfoPtr->dirBlock);
  2940. d1875 1
  2941. a1875 1
  2942. FsDirEntry *
  2943. d1878 1
  2944. a1878 1
  2945.     FsDirEntry        *dirEntryPtr;
  2946. d1885 1
  2947. a1885 1
  2948.     return((FsDirEntry *)
  2949. d1888 1
  2950. a1888 1
  2951.     FsFileDescriptor    *fdPtr;
  2952. d1914 3
  2953. a1916 3
  2954.     for (i = 0, dirEntryPtr = (FsDirEntry *)indexInfoPtr->dirBlock; 
  2955.          i < FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  2956.      i++,dirEntryPtr=(FsDirEntry *)((unsigned)dirEntryPtr+FS_DIR_BLOCK_SIZE)) {
  2957. d1918 1
  2958. a1918 1
  2959.         dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  2960. d1922 1
  2961. a1922 1
  2962.     return((FsDirEntry *) indexInfoPtr->dirBlock);
  2963. d1976 1
  2964. a1976 1
  2965.     FsFileDescriptor    *fileDescPtr;
  2966. d1987 1
  2967. a1987 1
  2968.     fileDescPtr->flags = FS_FD_ALLOC;
  2969. d2020 2
  2970. a2021 2
  2971.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  2972.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  2973. d2023 2
  2974. a2024 2
  2975.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  2976.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  2977. d2030 1
  2978. a2030 1
  2979.     if (numBlocks >= FS_NUM_DIRECT_BLOCKS) {
  2980. d2062 1
  2981. a2062 1
  2982.     FsDomainHeader    *domainPtr;
  2983. d2100 1
  2984. a2100 1
  2985.     FsDirEntry    *dirEntryPtr;
  2986. d2106 1
  2987. a2106 1
  2988.     dirEntryPtr = (FsDirEntry *)block;
  2989. d2110 1
  2990. a2110 1
  2991.     dirEntryPtr->recordLength = FsDirRecLength(length);
  2992. d2115 1
  2993. a2115 1
  2994.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  2995. d2119 1
  2996. a2119 1
  2997.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  2998. d2125 3
  2999. a2127 3
  3000.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  3001.      i < FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  3002.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  3003. d2129 1
  3004. a2129 1
  3005.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  3006. d2150 1
  3007. a2150 1
  3008. FsDirEntry *
  3009. d2153 1
  3010. a2153 1
  3011.     FsDirEntry        *dirEntryPtr;
  3012. d2163 1
  3013. a2163 1
  3014.     recordLength = FsDirRecLength(nameLength);
  3015. d2165 1
  3016. a2165 1
  3017.     while (dirEntryPtr != (FsDirEntry *) NULL) {
  3018. d2167 1
  3019. a2167 1
  3020.         oldRecLength = FsDirRecLength(dirEntryPtr->nameLength);
  3021. d2172 1
  3022. a2172 1
  3023.             (FsDirEntry *) ((int) dirEntryPtr + oldRecLength);
  3024. d2188 1
  3025. a2188 1
  3026.     if (leftOver > FS_DIR_ENTRY_HEADER) {
  3027. d2190 1
  3028. a2190 1
  3029.         dirEntryPtr =(FsDirEntry *) ((int) dirEntryPtr + recordLength);
  3030. d2224 1
  3031. a2224 1
  3032.     FsDirEntry        *dirEntryPtr;
  3033. d2230 1
  3034. a2230 1
  3035.     FsFileDescriptor    fileFD;
  3036. d2239 1
  3037. a2239 1
  3038.     if (dirEntryPtr == (FsDirEntry *)NULL) {
  3039. d2255 1
  3040. a2255 1
  3041.     printf("Device: /dev/%s, %d, %d\n",
  3042. d2260 1
  3043. a2260 1
  3044.     if (dirEntryPtr == (FsDirEntry *)NULL) {
  3045. @
  3046.  
  3047.  
  3048. 1.5
  3049. log
  3050. @Fixed bug in adding devices and setting the bitmap.
  3051. @
  3052. text
  3053. @d38 1
  3054. a38 1
  3055. static char rcsid[] = "$Header: fsmake.c,v 1.4 89/05/19 16:56:39 mnelson Locked $ SPRITE (Berkeley)";
  3056. a66 1
  3057. char *firstPartName = defaultFirstPartName;
  3058. a86 2
  3059.     {OPT_STRING, "initialPart", (Address)&firstPartName,
  3060.     "Name of initial partition (\"a\")"},
  3061. d215 1
  3062. a215 1
  3063.     char    firstPartitionName[64];
  3064. d251 1
  3065. a251 1
  3066.     sprintf(firstPartitionName, "/dev/%s%s", deviceName, firstPartName);
  3067. d254 1
  3068. a254 1
  3069.     partFID = open(firstPartitionName, O_RDONLY);
  3070. d256 1
  3071. a256 1
  3072.     partFID = open(firstPartitionName, O_RDWR);
  3073. d270 1
  3074. d272 2
  3075. d1544 3
  3076. d1548 6
  3077. d1572 2
  3078. a1573 2
  3079.     if (chdir("..") < 0) {
  3080.         perror("..");
  3081. d1577 11
  3082. a1594 1
  3083.     struct    stat    statBuf;
  3084. d1606 10
  3085. a1615 3
  3086.     if (lstat(fileName, &statBuf) < 0) {
  3087.         perror(fileName);
  3088.         exit(1);
  3089. a1643 1
  3090.  
  3091. d1663 1
  3092. a1663 1
  3093.         printf("Creating directory: %s\n", newPath);
  3094. d1674 1
  3095. a1674 1
  3096.         printf("Creating file: %s%s\n", path, fileName);
  3097. d1696 1
  3098. a1696 1
  3099.         printf("Creating symbolic link: %s%s -> %s\n", 
  3100. d1780 2
  3101. a1781 2
  3102.     if (chdir("..") < 0) {
  3103.     perror(".. (2)");
  3104. a1818 3
  3105.     } else  if (indexInfoPtr->blockAddr == FS_NIL_INDEX) {
  3106.     fprintf(stderr, "OpenDir: NIL block pointer\n");
  3107.     exit(1);
  3108. d1872 1
  3109. a1872 1
  3110.     if (indexInfoPtr->dirOffset == indexInfoPtr->fdPtr->lastByte + 1) {
  3111. d1874 1
  3112. a1874 2
  3113.      * We reached the end of the directory.  Write out the directory
  3114.      * block if necessary.
  3115. d1876 11
  3116. d1889 1
  3117. a1889 1
  3118.                     1, indexInfoPtr->dirBlock) < 0) {
  3119. d1891 1
  3120. a1891 1
  3121.                     indexInfoPtr->blockAddr);
  3122. d1895 19
  3123. a1913 1
  3124.     return((FsDirEntry *)NIL);
  3125. a1914 11
  3126.  
  3127.     if (indexInfoPtr->dirOffset < FS_BLOCK_SIZE) {
  3128.     /*
  3129.      * The next directory entry is in the current block.
  3130.      */
  3131.     return((FsDirEntry *)
  3132.             &(indexInfoPtr->dirBlock[indexInfoPtr->dirOffset]));
  3133.     } else {
  3134.     fprintf(stderr, "NextDirEntry: We are in the second block?\n");
  3135.     exit(1);
  3136.     }
  3137. d2246 1
  3138. a2246 1
  3139.     printf("Creating device: /dev/%s, %d, %d\n",
  3140. @
  3141.  
  3142.  
  3143. 1.4
  3144. log
  3145. @*** empty log message ***
  3146. @
  3147. text
  3148. @d38 1
  3149. a38 1
  3150. static char rcsid[] = "$Header: fsmake.c,v 1.3 89/05/15 19:39:56 mnelson Locked $ SPRITE (Berkeley)";
  3151. d1994 1
  3152. a1994 1
  3153. int fragMasks[FS_FRAGMENTS_PER_BLOCK] = {0x08, 0x0c, 0x0e, 0x0f};
  3154. d2212 1
  3155. a2212 1
  3156.     if (dirEntryPtr = (FsDirEntry *)NULL) {
  3157. @
  3158.  
  3159.  
  3160. 1.3
  3161. log
  3162. @*** empty log message ***
  3163. @
  3164. text
  3165. @d38 1
  3166. a38 1
  3167. static char rcsid[] = "$Header: fsmake.c,v 1.2 89/05/03 19:00:24 mnelson Exp $ SPRITE (Berkeley)";
  3168. d813 1
  3169. a813 1
  3170.         InitDesc(fileDescPtr, FS_FILE, 0, -1, -1);
  3171. d817 1
  3172. a817 1
  3173.         InitDesc(fileDescPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1);
  3174. d1587 1
  3175. a1587 1
  3176.     if (stat(fileName, &statBuf) < 0) {
  3177. d1627 2
  3178. a1628 1
  3179.         InitDesc(newFDPtr, FS_DIRECTORY, FS_BLOCK_SIZE, -1, -1);
  3180. d1640 2
  3181. a1641 1
  3182.     } else if (statBuf.st_mode & S_GFREG) {
  3183. d1647 28
  3184. a1674 1
  3185.         printf("Creating file: %s%s\n", path, fileName);
  3186. a1675 12
  3187.         /*
  3188.          * Copy the file over.
  3189.          */
  3190.         InitDesc(newFDPtr, FS_FILE, statBuf.st_size, -1, -1);
  3191.         fd = open(fileName, 0);
  3192.         if (fd < 0) {
  3193.         perror(fileName);
  3194.         exit(1);
  3195.         }
  3196.         blockNum = 0;
  3197.         toRead = statBuf.st_size;
  3198.         len = read(fd, fileBlock, FS_BLOCK_SIZE);
  3199. d1726 3
  3200. d1927 1
  3201. a1927 1
  3202. InitDesc(fileDescPtr, fileType, numBytes, devType, devUnit)
  3203. d1933 2
  3204. d1942 2
  3205. a1943 2
  3206.     fileDescPtr->uid = 0;
  3207.     fileDescPtr->gid = 0;
  3208. d2201 1
  3209. a2201 1
  3210.     InitDesc(&fileFD, FS_DEVICE, 0, devType, devUnit);
  3211. @
  3212.  
  3213.  
  3214. 1.2
  3215. log
  3216. @*** empty log message ***
  3217. @
  3218. text
  3219. @d38 1
  3220. a38 1
  3221. static char rcsid[] = "$Header: fsmake.c,v 1.1 89/05/02 10:50:04 mnelson Locked $ SPRITE (Berkeley)";
  3222. d1679 2
  3223. a1680 1
  3224.             indIndexPtr[blockNum - FS_NUM_DIRECT_BLOCKS] = freeBlockNum;
  3225. d1934 2
  3226. a1935 2
  3227.     fileDescPtr->devType = -1;
  3228.     fileDescPtr->devUnit = -1;
  3229. d2182 3
  3230. @
  3231.  
  3232.  
  3233. 1.1
  3234. log
  3235. @Initial revision
  3236. @
  3237. text
  3238. @d6 29
  3239. a34 2
  3240.  * Copyright (C) 1986 Regents of the University of California
  3241.  * All rights reserved.
  3242. d38 1
  3243. a38 1
  3244. static char rcsid[] = "$Header: /sprite/src/admin/fsmake/RCS/fsmake.c,v 1.6 89/03/03 17:08:18 jhh Exp $ SPRITE (Berkeley)";
  3245. d48 6
  3246. a61 2
  3247. Boolean makeFile = FALSE;    /* Make a file in the root directory,
  3248.                  * this is used when testing the filesystem */
  3249. a63 7
  3250.  
  3251. /*
  3252.  * The following are used to go from a command line like
  3253.  * makeFilesystem -D rsd0 -P b
  3254.  * to /dev/rsd0a     - for the partition that has the disk label
  3255.  * and to /dev/rsd0b    - for the partition to format.
  3256.  */
  3257. d68 6
  3258. a73 4
  3259. char defaultDevDirectory[] = "/dev/";
  3260. char *devDirectory = defaultDevDirectory;
  3261. char *diskType = NULL;
  3262. int  spriteID = 0;
  3263. a79 2
  3264.     {OPT_TRUE, "file", (Address)&makeFile,
  3265.     "Make a file in the root directory (FALSE)"},
  3266. a87 2
  3267.     {OPT_STRING, "dir", (Address)&devDirectory,
  3268.     "Name of device directory (\"/dev/\")"},
  3269. d94 4
  3270. d102 17
  3271. d125 6
  3272. a130 7
  3273. void        SetRootFileDescriptor();
  3274. void        SetBadBlockFileDescriptor();
  3275. void        SetLostFoundFileDescriptor();
  3276. void        SetEmptyFileDescriptor();
  3277. ReturnStatus    WriteFileDesc();
  3278. ReturnStatus    WriteFileDescBitmap();
  3279. ReturnStatus    WriteBitmap();
  3280. d133 12
  3281. d146 48
  3282. a218 1
  3283.     int        firstPartFID;
  3284. d232 1
  3285. a232 1
  3286.     fprintf(stderr, "No sprite ID\n");
  3287. d254 1
  3288. a254 3
  3289.     (void) strcpy(firstPartitionName, devDirectory);    /* eg. /dev/ */
  3290.     (void) strcat(firstPartitionName, deviceName);    /* eg. /dev/rxy0 */
  3291.     (void) strcat(firstPartitionName, firstPartName);    /* eg. /dev/rxy0a */
  3292. d257 1
  3293. a257 1
  3294.     firstPartFID = open(firstPartitionName, O_RDONLY);
  3295. d259 1
  3296. a259 1
  3297.     firstPartFID = open(firstPartitionName, O_RDWR);
  3298. d261 1
  3299. a261 1
  3300.     if (firstPartFID < 0 ) {
  3301. a266 1
  3302.     status = MakeFilesystem(firstPartFID, partName[0] - 'a', spriteID);
  3303. d268 1
  3304. a268 33
  3305.     fflush(stderr);
  3306.     fflush(stdout);
  3307.     (void)close(firstPartFID);
  3308.     exit(status);
  3309. }
  3310.  
  3311. /*
  3312.  *----------------------------------------------------------------------
  3313.  *
  3314.  * MakeFilesystem --
  3315.  *
  3316.  *    Format a disk partition, or domain, to be an empty filesystem.
  3317.  *
  3318.  * Results:
  3319.  *    An error code.
  3320.  *
  3321.  * Side effects:
  3322.  *    Write all over the disk partition.
  3323.  *
  3324.  *----------------------------------------------------------------------
  3325.  */
  3326. int
  3327. MakeFilesystem(firstPartFID, partition, spriteID)
  3328.     int firstPartFID;    /* Handle on the first partition of the disk */
  3329.     int partition;    /* Index of parition that is to be formatted */
  3330.     int spriteID;    /* Host ID of the machine with the disks, this
  3331.              * gets written on the disk and used at boot time */
  3332. {
  3333.     int            status;
  3334.     Disk_Info        *diskInfoPtr;
  3335.     FsDomainHeader     *headerPtr;
  3336.     FsSummaryInfo     *summaryPtr;
  3337.  
  3338. d273 1
  3339. a273 1
  3340.     diskInfoPtr = Disk_ReadDiskInfo(firstPartFID, partition);
  3341. d279 1
  3342. a279 1
  3343.         diskInfoPtr = ScanDiskTab(firstPartFID, partition, diskType);
  3344. d287 1
  3345. a287 1
  3346.     headerPtr = (FsDomainHeader *)
  3347. d289 3
  3348. a291 2
  3349.     SetDomainHeader(diskInfoPtr, headerPtr, spriteID, partition);
  3350.     Disk_PrintDomainHeader(headerPtr);
  3351. d294 2
  3352. a295 2
  3353.     status = Disk_SectorWrite(firstPartFID, diskInfoPtr->domainSector,
  3354.                 diskInfoPtr->numDomainSectors, (Address)headerPtr);
  3355. d301 1
  3356. d303 1
  3357. a303 1
  3358.     SetSummaryInfo(diskInfoPtr, headerPtr, summaryPtr);
  3359. d306 1
  3360. a306 1
  3361.     status = Disk_SectorWrite(firstPartFID, diskInfoPtr->summarySector, 1,
  3362. d314 42
  3363. a355 5
  3364.     WriteFileDesc(headerPtr, firstPartFID);
  3365.     WriteBitmap(headerPtr, firstPartFID);
  3366.     WriteRootDirectory(headerPtr, firstPartFID);
  3367.     WriteLostFoundDirectory(headerPtr, firstPartFID);
  3368.     return(0);
  3369. d376 1
  3370. a376 6
  3371. SetDomainHeader(diskInfoPtr, headerPtr, spriteID, partition)
  3372.     Disk_Info        *diskInfoPtr;    /* Information from the super block */
  3373.     FsDomainHeader    *headerPtr;    /* Reference to domain header to fill
  3374.                      * in */
  3375.     int            spriteID;    /* Host ID of machine with the disks */
  3376.     int            partition;    /* Index of partition to format */
  3377. d380 3
  3378. a382 3
  3379.     headerPtr->magic = FS_DOMAIN_MAGIC;
  3380.     headerPtr->firstCylinder = diskInfoPtr->firstCylinder;
  3381.     headerPtr->numCylinders = diskInfoPtr->numCylinders;
  3382. d392 4
  3383. a395 4
  3384.     headerPtr->device.serverID = spriteID;
  3385.     headerPtr->device.type = -1;
  3386.     headerPtr->device.unit = partition;
  3387.     headerPtr->device.data = (ClientData)-1;
  3388. d397 2
  3389. a398 2
  3390.     geoPtr = &headerPtr->geometry;
  3391.     SetDiskGeometry(diskInfoPtr, geoPtr);
  3392. d400 1
  3393. a400 1
  3394.     SetDomainParts(diskInfoPtr, headerPtr);
  3395. d425 1
  3396. a425 2
  3397. SetDiskGeometry(diskInfoPtr, geoPtr)
  3398.     register Disk_Info    *diskInfoPtr;    /* Basic geometry information */
  3399. d611 1
  3400. a611 3
  3401. SetDomainParts(diskInfoPtr, headerPtr)
  3402.     register Disk_Info        *diskInfoPtr;
  3403.     register FsDomainHeader    *headerPtr;
  3404. d626 1
  3405. a626 1
  3406.     geoPtr = &headerPtr->geometry;
  3407. d652 1
  3408. a652 1
  3409.     headerPtr->fdBitmapOffset = offset;
  3410. d654 3
  3411. a656 3
  3412.     headerPtr->fdBitmapBlocks = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  3413.     numBlocks          -= headerPtr->fdBitmapBlocks;
  3414.     offset              += headerPtr->fdBitmapBlocks;
  3415. d658 2
  3416. a659 2
  3417.     headerPtr->fileDescOffset = offset;
  3418.     headerPtr->numFileDesc      = numFiles;
  3419. d666 2
  3420. a667 2
  3421.     headerPtr->bitmapOffset      = offset;
  3422.     headerPtr->dataOffset      = ((offset-1) / geoPtr->blocksPerCylinder + 1)
  3423. d669 1
  3424. a669 1
  3425.     headerPtr->dataBlocks      = headerPtr->numCylinders *
  3426. d671 2
  3427. a672 2
  3428.                       headerPtr->dataOffset;
  3429.     bitmapBytes          = (headerPtr->dataBlocks * DISK_KBYTES_PER_BLOCK -
  3430. d674 1
  3431. a674 1
  3432.     headerPtr->bitmapBlocks      = (bitmapBytes - 1) / FS_BLOCK_SIZE + 1;
  3433. d680 2
  3434. a681 2
  3435.     if (headerPtr->dataOffset - headerPtr->bitmapOffset <
  3436.         headerPtr->bitmapBlocks) {
  3437. d687 2
  3438. a688 2
  3439.         numBlocksNeeded = headerPtr->bitmapBlocks -
  3440.         (headerPtr->dataOffset - headerPtr->bitmapOffset);
  3441. d690 2
  3442. a691 2
  3443.     } else if (headerPtr->dataOffset - headerPtr->bitmapOffset >
  3444.             headerPtr->bitmapBlocks) {
  3445. d698 2
  3446. a699 2
  3447.         extraBlocks = headerPtr->dataOffset - headerPtr->bitmapOffset -
  3448.             headerPtr->bitmapBlocks;
  3449. d702 3
  3450. a704 3
  3451.     } while (headerPtr->dataOffset - headerPtr->bitmapOffset !=
  3452.         headerPtr->bitmapBlocks);
  3453.     headerPtr->dataCylinders    = headerPtr->dataBlocks /
  3454. d725 1
  3455. a725 5
  3456. SetSummaryInfo(diskInfoPtr, headerPtr, summaryPtr)
  3457.     Disk_Info        *diskInfoPtr;    /* Information from the super block */
  3458.     FsDomainHeader    *headerPtr;    /* Domain header to summarize */
  3459.     FsSummaryInfo    *summaryPtr;    /* Reference to summary info to 
  3460.                      * fill in */
  3461. d732 1
  3462. a732 2
  3463.      * 12 blocks are already allocated, 4 for the root directory,
  3464.      * and 8 more for lost+found.
  3465. d734 2
  3466. a735 2
  3467.     summaryPtr->numFreeKbytes = headerPtr->dataBlocks * (FS_BLOCK_SIZE / 1024)
  3468.                 - 12;
  3469. d737 2
  3470. a738 2
  3471.      * 4 file descriptors are already used, 0 and 1 are reserved,
  3472.      * 2 is for the root, and 3 is for lost+found.
  3473. d740 1
  3474. a740 4
  3475.     summaryPtr->numFreeFileDesc = headerPtr->numFileDesc - 4;
  3476.     if (makeFile) {
  3477.     summaryPtr->numFreeFileDesc--;
  3478.     }
  3479. d765 1
  3480. a765 1
  3481.  * WriteFileDesc --
  3482. d777 2
  3483. a778 4
  3484. ReturnStatus
  3485. WriteFileDesc(headerPtr, firstPartFID)
  3486.     register FsDomainHeader    *headerPtr;
  3487.     int                firstPartFID;
  3488. d780 1
  3489. a780 1
  3490.     ReturnStatus        status;
  3491. d786 1
  3492. a786 1
  3493.     bitmap = MakeFileDescBitmap(headerPtr);
  3494. d788 3
  3495. a790 3
  3496.     status = Disk_BlockWrite(firstPartFID, headerPtr,
  3497.                 headerPtr->fdBitmapOffset,
  3498.                 headerPtr->fdBitmapBlocks, (Address)bitmap);
  3499. d792 2
  3500. a793 1
  3501.         return(status);
  3502. d813 3
  3503. a815 1
  3504.         SetBadBlockFileDescriptor(fileDescPtr);
  3505. d817 5
  3506. a821 5
  3507.         SetRootFileDescriptor(fileDescPtr);
  3508.     } else if (index == FS_LOST_FOUND_FILE_NUMBER) {
  3509.         SetLostFoundFileDescriptor(fileDescPtr);
  3510.     } else if ((index == FS_LOST_FOUND_FILE_NUMBER+1) && makeFile) {
  3511.         SetEmptyFileDescriptor(fileDescPtr);
  3512. d831 2
  3513. a832 2
  3514.     status = Disk_BlockWrite(firstPartFID, headerPtr, 
  3515.                  headerPtr->fileDescOffset,
  3516. d835 2
  3517. a836 1
  3518.         return(status);
  3519. d854 1
  3520. a854 1
  3521.          index < headerPtr->numFileDesc;
  3522. d856 2
  3523. a857 2
  3524.         status = Disk_BlockWrite(firstPartFID, headerPtr,
  3525.              headerPtr->fileDescOffset + (index/FS_FILE_DESC_PER_BLOCK),
  3526. d860 3
  3527. a862 1
  3528.         return(status);
  3529. a864 2
  3530.     } else {
  3531.     status = 0;
  3532. a865 1
  3533.     return(status);
  3534. a866 22
  3535.  
  3536. /*
  3537.  *----------------------------------------------------------------------
  3538.  *
  3539.  * SetRootFileDescriptor --
  3540.  *
  3541.  *    Set up the file descriptor for the root directory.
  3542.  *
  3543.  * Results:
  3544.  *    Fill in the file descriptor.
  3545.  *
  3546.  * Side effects:
  3547.  *    None.
  3548.  *
  3549.  *----------------------------------------------------------------------
  3550.  */
  3551. void
  3552. SetRootFileDescriptor(fileDescPtr)
  3553.     register FsFileDescriptor *fileDescPtr;
  3554. {
  3555.     Time    time;
  3556.     int        index;
  3557. a867 39
  3558.     fileDescPtr->flags = FS_FD_ALLOC;
  3559.     fileDescPtr->fileType = FS_DIRECTORY;
  3560.     fileDescPtr->permissions = 0755;
  3561.     fileDescPtr->uid = 0;
  3562.     fileDescPtr->gid = 0;
  3563.     fileDescPtr->lastByte = FS_BLOCK_SIZE-1;
  3564.     fileDescPtr->firstByte = -1;
  3565.     fileDescPtr->numLinks = 3;
  3566.     /*
  3567.      * Can't know device information because that depends on
  3568.      * the way the system is configured.
  3569.      */
  3570.     fileDescPtr->devServerID = -1;
  3571.     fileDescPtr->devType = -1;
  3572.     fileDescPtr->devUnit = -1;
  3573.  
  3574.     /*
  3575.      * Set the time stamps.  This assumes that universal time, not local
  3576.      * time, is used for time stamps.
  3577.      */
  3578.     gettimeofday(&time, NULL);
  3579.     fileDescPtr->createTime = time.seconds;
  3580.     fileDescPtr->accessTime = 0;
  3581.     fileDescPtr->descModifyTime = time.seconds;
  3582.     fileDescPtr->dataModifyTime = time.seconds;
  3583.  
  3584.     /*
  3585.      * Place the data in the first filesystem block.
  3586.      */
  3587.     fileDescPtr->direct[0] = 0;
  3588.     for (index = 1; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  3589.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  3590.     }
  3591.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  3592.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  3593.     }
  3594.     fileDescPtr->numKbytes = 4;
  3595.     fileDescPtr->version = 1;
  3596. }
  3597. a871 180
  3598.  * SetBadBlockFileDescriptor --
  3599.  *
  3600.  *    Set up the file descriptor for the bad block file.
  3601.  *
  3602.  * Results:
  3603.  *    Fill in the file descriptor.
  3604.  *
  3605.  * Side effects:
  3606.  *    None.
  3607.  *
  3608.  *----------------------------------------------------------------------
  3609.  */
  3610. void
  3611. SetBadBlockFileDescriptor(fileDescPtr)
  3612.     register FsFileDescriptor *fileDescPtr;
  3613. {
  3614.     Time    time;
  3615.     int        index;
  3616.  
  3617.     fileDescPtr->flags = FS_FD_ALLOC;
  3618.     fileDescPtr->fileType = FS_FILE;
  3619.     fileDescPtr->permissions = 0000;
  3620.     fileDescPtr->uid = 0;
  3621.     fileDescPtr->gid = 0;
  3622.     fileDescPtr->lastByte = -1;
  3623.     fileDescPtr->firstByte = -1;
  3624.     fileDescPtr->numLinks = 0;        /* Intentionally unreferenced */
  3625.     /*
  3626.      * Can't know device information because that depends on
  3627.      * the way the system is configured.
  3628.      */
  3629.     fileDescPtr->devServerID = -1;
  3630.     fileDescPtr->devType = -1;
  3631.     fileDescPtr->devUnit = -1;
  3632.  
  3633.     /*
  3634.      * Set the time stamps.  This assumes that universal time, not local
  3635.      * time, is used for time stamps.
  3636.      */
  3637.     gettimeofday(&time, NULL);
  3638.     fileDescPtr->createTime = time.seconds;
  3639.     fileDescPtr->accessTime = 0;
  3640.     fileDescPtr->descModifyTime = time.seconds;
  3641.     fileDescPtr->dataModifyTime = time.seconds;
  3642.  
  3643.     /*
  3644.      * Place the data in the first filesystem block.
  3645.      */
  3646.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  3647.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  3648.     }
  3649.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  3650.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  3651.     }
  3652.     fileDescPtr->numKbytes = 0;
  3653.     fileDescPtr->version = 1;
  3654. }
  3655.  
  3656. /*
  3657.  *----------------------------------------------------------------------
  3658.  *
  3659.  * SetLostFoundFileDescriptor --
  3660.  *
  3661.  *    Set up the file descriptor for the lost and found directory.
  3662.  *
  3663.  * Results:
  3664.  *    Fill in the file descriptor.
  3665.  *
  3666.  * Side effects:
  3667.  *    None.
  3668.  *
  3669.  *----------------------------------------------------------------------
  3670.  */
  3671. void
  3672. SetLostFoundFileDescriptor(fileDescPtr)
  3673.     register FsFileDescriptor *fileDescPtr;
  3674. {
  3675.     Time    time;
  3676.     int        index;
  3677.  
  3678.     fileDescPtr->flags = FS_FD_ALLOC;
  3679.     fileDescPtr->fileType = FS_DIRECTORY;
  3680.     fileDescPtr->permissions = 0755;
  3681.     fileDescPtr->uid = 0;
  3682.     fileDescPtr->gid = 0;
  3683.     fileDescPtr->lastByte = FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE - 1;
  3684.     fileDescPtr->firstByte = -1;
  3685.     fileDescPtr->numLinks = 2;
  3686.     /*
  3687.      * Can't know device information because that depends on
  3688.      * the way the system is configured.
  3689.      */
  3690.     fileDescPtr->devServerID = -1;
  3691.     fileDescPtr->devType = -1;
  3692.     fileDescPtr->devUnit = -1;
  3693.  
  3694.     /*
  3695.      * Set the time stamps.  This assumes that universal time, not local
  3696.      * time, is used for time stamps.
  3697.      */
  3698.     gettimeofday(&time, NULL);
  3699.     fileDescPtr->createTime = time.seconds;
  3700.     fileDescPtr->accessTime = 0;
  3701.     fileDescPtr->descModifyTime = time.seconds;
  3702.     fileDescPtr->dataModifyTime = time.seconds;
  3703.  
  3704.     for (index = 0; index < FS_NUM_LOST_FOUND_BLOCKS ; index++) {
  3705.     fileDescPtr->direct[index] = FS_FRAGMENTS_PER_BLOCK * (index + 1);
  3706.     }
  3707.     for (; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  3708.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  3709.     }
  3710.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  3711.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  3712.     }
  3713.     fileDescPtr->numKbytes = 8;
  3714.     fileDescPtr->version = 1;
  3715. }
  3716.  
  3717. /*
  3718.  *----------------------------------------------------------------------
  3719.  *
  3720.  * SetEmptyFileDescriptor --
  3721.  *
  3722.  *    Set up a file descriptor for an empty file.
  3723.  *
  3724.  * Results:
  3725.  *    Fill in the file descriptor.
  3726.  *
  3727.  * Side effects:
  3728.  *    None.
  3729.  *
  3730.  *----------------------------------------------------------------------
  3731.  */
  3732. void
  3733. SetEmptyFileDescriptor(fileDescPtr)
  3734.     register FsFileDescriptor *fileDescPtr;
  3735. {
  3736.     Time    time;
  3737.     int        index;
  3738.  
  3739.     fileDescPtr->flags = FS_FD_ALLOC;
  3740.     fileDescPtr->fileType = FS_FILE;
  3741.     fileDescPtr->permissions = 0666;
  3742.     fileDescPtr->uid = 0;
  3743.     fileDescPtr->gid = 0;
  3744.     fileDescPtr->lastByte = -1;
  3745.     fileDescPtr->firstByte = -1;
  3746.     fileDescPtr->numLinks = 1;
  3747.     /*
  3748.      * Can't know device information because that depends on
  3749.      * the way the system is configured.
  3750.      */
  3751.     fileDescPtr->devServerID = -1;
  3752.     fileDescPtr->devType = -1;
  3753.     fileDescPtr->devUnit = -1;
  3754.  
  3755.     /*
  3756.      * Set the time stamps.  This assumes that universal time, not local
  3757.      * time, is used for time stamps.
  3758.      */
  3759.     gettimeofday(&time, NULL);
  3760.     fileDescPtr->createTime = time.seconds;
  3761.     fileDescPtr->accessTime = 0;
  3762.     fileDescPtr->descModifyTime = time.seconds;
  3763.     fileDescPtr->dataModifyTime = time.seconds;
  3764.  
  3765.     for (index = 0; index < FS_NUM_DIRECT_BLOCKS ; index++) {
  3766.     fileDescPtr->direct[index] = FS_NIL_INDEX;
  3767.     }
  3768.     for (index = 0; index < FS_NUM_INDIRECT_BLOCKS ; index++) {
  3769.     fileDescPtr->indirect[index] = FS_NIL_INDEX;
  3770.     }
  3771.     fileDescPtr->numKbytes = 0;
  3772.     fileDescPtr->version = 1;
  3773. }
  3774.  
  3775. /*
  3776.  *----------------------------------------------------------------------
  3777.  *
  3778. d885 1
  3779. a885 2
  3780. MakeFileDescBitmap(headerPtr)
  3781.     register FsDomainHeader *headerPtr;
  3782. d893 1
  3783. a893 1
  3784.     bitmap = (char *)malloc((unsigned) headerPtr->fdBitmapBlocks *
  3785. d895 1
  3786. a895 1
  3787.     bzero((Address)bitmap, headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE);
  3788. d898 1
  3789. a898 1
  3790.      * Reserve file descriptors 0, 1, 2, and 3.  File number 0 is not used at 
  3791. a900 2
  3792.      * File number 3 (FS_LOST_FOUND_NUMBER) is the directory where lost
  3793.      * files are stored.
  3794. d904 1
  3795. a904 1
  3796.     bitmap[0] |= 0xf0;
  3797. a906 6
  3798.      * Reserve file descriptor # 4 for an empty file.
  3799.      */
  3800.     if (makeFile) {
  3801.     bitmap[0] |= 0x08;
  3802.     }
  3803.     /*
  3804. d910 2
  3805. a911 2
  3806.     index = headerPtr->numFileDesc / BITS_PER_BYTE;
  3807.     if (headerPtr->numFileDesc % BITS_PER_BYTE) {
  3808. d916 1
  3809. a916 1
  3810.     for (bitIndex = headerPtr->numFileDesc % BITS_PER_BYTE;
  3811. d923 1
  3812. a923 1
  3813.     for ( ; index < headerPtr->fdBitmapBlocks * FS_BLOCK_SIZE; index++) {
  3814. d928 1
  3815. a928 1
  3816.     Disk_PrintFileDescBitmap(headerPtr, bitmap);
  3817. d936 1
  3818. a936 1
  3819.  * WriteBitmap --
  3820. d939 1
  3821. a939 2
  3822.  *    first 1K fragment is allocated to the root directory and 8K is
  3823.  *    allocated to lost and found.
  3824. d949 2
  3825. a950 4
  3826. ReturnStatus
  3827. WriteBitmap(headerPtr, firstPartFID)
  3828.     register FsDomainHeader    *headerPtr;
  3829.     int                firstPartFID;
  3830. d958 2
  3831. a959 2
  3832.     bitmap = (char *)malloc((unsigned) headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  3833.     bzero(bitmap, headerPtr->bitmapBlocks * FS_BLOCK_SIZE);
  3834. d961 1
  3835. a961 2
  3836.      * Set the bit corresponding to the 4K used for the root directory
  3837.      * and the next 8K reserved for lost and found.
  3838. d967 1
  3839. a967 2
  3840.     bitmap[0] |= 0xff;
  3841.     bitmap[1] |= 0xf0;
  3842. d973 1
  3843. a973 1
  3844.     kbytesPerCyl = headerPtr->geometry.blocksPerCylinder * DISK_KBYTES_PER_BLOCK;
  3845. d993 1
  3846. a993 1
  3847.          index < headerPtr->dataBlocks * DISK_KBYTES_PER_BLOCK / BITS_PER_BYTE;
  3848. d1004 2
  3849. a1005 2
  3850.     for (index = headerPtr->dataCylinders * bitmapBytesPerCyl;
  3851.      index < headerPtr->bitmapBlocks * FS_BLOCK_SIZE;
  3852. d1010 1
  3853. a1010 2
  3854.     Disk_PrintDataBlockBitmap(headerPtr, bitmap);
  3855.     status = 0;
  3856. d1012 7
  3857. a1018 3
  3858.     status = Disk_BlockWrite(firstPartFID, headerPtr, 
  3859.                  headerPtr->bitmapOffset,
  3860.                  headerPtr->bitmapBlocks, (Address)bitmap);
  3861. a1019 1
  3862.     return(status);
  3863. d1021 1
  3864. d1038 2
  3865. a1039 4
  3866. ReturnStatus
  3867. WriteRootDirectory(headerPtr, firstPartFID)
  3868.     FsDomainHeader    *headerPtr;
  3869.     int            firstPartFID;
  3870. a1043 2
  3871.     char    *fileName;
  3872.     int        length;
  3873. d1048 1
  3874. a1048 1
  3875.     dirEntryPtr = (FsDirEntry *)block;
  3876. a1049 53
  3877.     fileName = ".";
  3878.     length = strlen(fileName);
  3879.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  3880.     dirEntryPtr->recordLength = FsDirRecLength(length);
  3881.     dirEntryPtr->nameLength = length;
  3882.     strcpy(dirEntryPtr->fileName, fileName);
  3883.     offset = dirEntryPtr->recordLength;
  3884.  
  3885.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  3886.     fileName = "..";
  3887.     length = strlen(fileName);
  3888.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  3889.     dirEntryPtr->recordLength = FsDirRecLength(length);
  3890.     dirEntryPtr->nameLength = length;
  3891.     strcpy(dirEntryPtr->fileName, fileName);
  3892.     offset += dirEntryPtr->recordLength;
  3893.  
  3894.     /*
  3895.      * Add lost and found.
  3896.      */
  3897.  
  3898.     dirEntryPtr = (FsDirEntry *) ((int)block + offset);
  3899.     fileName = "lost+found";
  3900.     length = strlen(fileName);
  3901.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER;
  3902.     dirEntryPtr->nameLength = length;
  3903.     strcpy(dirEntryPtr->fileName, fileName);
  3904.  
  3905.     if (!makeFile) {
  3906.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  3907.     } else {
  3908.     dirEntryPtr->recordLength = FsDirRecLength(length);
  3909.     offset += dirEntryPtr->recordLength;
  3910.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  3911.     fileName = "testFile";
  3912.     length = strlen(fileName);
  3913.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER + 1;
  3914.     dirEntryPtr->nameLength = length;
  3915.     strcpy(dirEntryPtr->fileName, fileName);
  3916.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  3917.     }
  3918.     /*
  3919.      * Fill out the rest of the directory with empty blocks.
  3920.      */
  3921.  
  3922.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  3923.      i < FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  3924.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  3925.      dirEntryPtr->fileNumber = 0;
  3926.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  3927.      dirEntryPtr->nameLength = 0;
  3928.     }
  3929.  
  3930. a1057 9
  3931.     offset += dirEntryPtr->recordLength;
  3932.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  3933.     Disk_PrintDirEntry(dirEntryPtr);
  3934.     if (makeFile) {
  3935.         offset += dirEntryPtr->recordLength;
  3936.         dirEntryPtr = (FsDirEntry *)((int)block + offset);
  3937.         Disk_PrintDirEntry(dirEntryPtr);
  3938.     }
  3939.     status = 0;
  3940. d1064 6
  3941. a1069 2
  3942.     status = Disk_BlockWrite(firstPartFID, headerPtr,
  3943.                  headerPtr->dataOffset, 1, block);
  3944. a1070 1
  3945.     return(status);
  3946. d1072 1
  3947. a1072 1
  3948.  
  3949. d1074 1
  3950. a1074 13
  3951.  *----------------------------------------------------------------------
  3952.  *
  3953.  * WriteLostFoundDirectory --
  3954.  *
  3955.  *    Write the data blocks of the lost and found directory.
  3956.  *
  3957.  * Results:
  3958.  *    A return code from the writes.
  3959.  *
  3960.  * Side effects:
  3961.  *    Write the root directory"s data block.
  3962.  *
  3963.  *----------------------------------------------------------------------
  3964. a1075 60
  3965. ReturnStatus
  3966. WriteLostFoundDirectory(headerPtr, firstPartFID)
  3967.     register FsDomainHeader    *headerPtr;
  3968.     int                firstPartFID;
  3969. {
  3970.     int        status;
  3971.     char    *block;
  3972.     FsDirEntry    *dirEntryPtr;
  3973.     char    *fileName;
  3974.     int        length;
  3975.     int        offset;
  3976.     int        i;
  3977.  
  3978.     block = (char *)malloc(FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE);
  3979.     dirEntryPtr = (FsDirEntry *)block;
  3980.  
  3981.     fileName = ".";
  3982.     length = strlen(fileName);
  3983.     dirEntryPtr->fileNumber = FS_LOST_FOUND_FILE_NUMBER;
  3984.     dirEntryPtr->recordLength = FsDirRecLength(length);
  3985.     dirEntryPtr->nameLength = length;
  3986.     strcpy(dirEntryPtr->fileName, fileName);
  3987.     offset = dirEntryPtr->recordLength;
  3988.  
  3989.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  3990.     fileName = "..";
  3991.     length = strlen(fileName);
  3992.     dirEntryPtr->fileNumber = FS_ROOT_FILE_NUMBER;
  3993.     dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE - offset;
  3994.     dirEntryPtr->nameLength = length;
  3995.     strcpy(dirEntryPtr->fileName, fileName);
  3996.  
  3997.     /*
  3998.      * Fill out the rest of the directory with empty blocks.
  3999.      */
  4000.  
  4001.     for (dirEntryPtr = (FsDirEntry *)&block[FS_DIR_BLOCK_SIZE], i = 1; 
  4002.      i < FS_NUM_LOST_FOUND_BLOCKS * FS_BLOCK_SIZE / FS_DIR_BLOCK_SIZE;
  4003.      i++,dirEntryPtr=(FsDirEntry *)((int)dirEntryPtr + FS_DIR_BLOCK_SIZE)) {
  4004.      dirEntryPtr->fileNumber = 0;
  4005.      dirEntryPtr->recordLength = FS_DIR_BLOCK_SIZE;
  4006.      dirEntryPtr->nameLength = 0;
  4007.     }
  4008.     if (printOnly) {
  4009.     printf("Lost+found Directory\n");
  4010.     offset = 0;
  4011.     dirEntryPtr = (FsDirEntry *)block;
  4012.     Disk_PrintDirEntry(dirEntryPtr);
  4013.     offset += dirEntryPtr->recordLength;
  4014.     dirEntryPtr = (FsDirEntry *)((int)block + offset);
  4015.     Disk_PrintDirEntry(dirEntryPtr);
  4016.     status = 0;
  4017.     } else {
  4018.     status = Disk_BlockWrite(firstPartFID, headerPtr, 
  4019.                  headerPtr->dataOffset + 1,
  4020.                      FS_NUM_LOST_FOUND_BLOCKS, block);
  4021.     }
  4022.     return(status);
  4023. }
  4024.  
  4025. d1089 1
  4026. d1109 1
  4027. a1109 4
  4028. ScanDiskTab(firstPartFID, partition, diskType)
  4029.     int        firstPartFID;
  4030.     char    partition;
  4031.     char    *diskType;
  4032. d1236 1
  4033. a1236 1
  4034.      * Set up a disk header and write it to sector 16.
  4035. d1245 1
  4036. d1257 1
  4037. a1257 1
  4038.     header.partition = partition - 'a';
  4039. d1271 14
  4040. d1287 1
  4041. a1287 1
  4042.     status = Disk_SectorWrite(firstPartFID, 16, 1, (Address)headerPtr);
  4043. d1311 881
  4044. @
  4045.